home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / gcc263-src.lha / gcc-2.6.3 / config / i386 / i386.md < prev    next >
Text File  |  1994-10-31  |  154KB  |  5,680 lines

  1. ;; GCC machine description for Intel X86.
  2. ;; Copyright (C) 1988, 1994 Free Software Foundation, Inc.
  3. ;; Mostly by William Schelter.
  4.  
  5. ;; This file is part of GNU CC.
  6.  
  7. ;; GNU CC is free software; you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation; either version 2, or (at your option)
  10. ;; any later version.
  11.  
  12. ;; GNU CC is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. ;; GNU General Public License for more details.
  16.  
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU CC; see the file COPYING.  If not, write to
  19. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  
  22. ;; The original PO technology requires these to be ordered by speed,
  23. ;; so that assigner will pick the fastest.
  24.  
  25. ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
  26.  
  27. ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
  28. ;; updates for most instructions.
  29.  
  30. ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
  31. ;; constraint letters.
  32.  
  33. ;; the special asm out single letter directives following a '%' are:
  34. ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
  35. ;;     operands[1].
  36. ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
  37. ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
  38. ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
  39. ;; 'S' Print the opcode suffix for a 32-bit float opcode.
  40. ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
  41.  
  42. ;; 'b' Print the QImode name of the register for the indicated operand.
  43. ;;     %b0 would print %al if operands[0] is reg 0.
  44. ;; 'w' Likewise, print the HImode name of the register.
  45. ;; 'k' Likewise, print the SImode name of the register.
  46. ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
  47. ;; 'y' Print "st(0)" instead of "st" as a register.
  48. ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
  49.  
  50. ;; UNSPEC usage:
  51. ;; 0  This is a `scas' operation.  The mode of the UNSPEC is always SImode.
  52. ;;    operand 0 is the memory address to scan.
  53. ;;    operand 1 is a register containing the value to scan for.  The mode
  54. ;;       of the scas opcode will be the same as the mode of this operand.
  55. ;;    operand 2 is the known alignment of operand 0.
  56. ;; 1  This is a `sin' operation.  The mode of the UNSPEC is MODE_FLOAT.
  57. ;;    operand 0 is the argument for `sin'.
  58. ;; 2  This is a `cos' operation.  The mode of the UNSPEC is MODE_FLOAT.
  59. ;;    operand 0 is the argument for `cos'.
  60.  
  61. ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
  62. ;; But restricting MEM here would mean that gcc could not remove a redundant
  63. ;; test in cases like "incl MEM / je TARGET".
  64. ;;
  65. ;; We don't want to allow a constant operand for test insns because
  66. ;; (set (cc0) (const_int foo)) has no mode information.  Such insns will
  67. ;; be folded while optimizing anyway.
  68.  
  69. ;; All test insns have expanders that save the operands away without
  70. ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
  71. ;; after the tstM or cmp) will actually emit the tstM or cmpM.
  72.  
  73. (define_insn "tstsi_1"
  74.   [(set (cc0)
  75.     (match_operand:SI 0 "nonimmediate_operand" "rm"))]
  76.   ""
  77.   "*
  78. {
  79.   if (REG_P (operands[0]))
  80.     return AS2 (test%L0,%0,%0);
  81.  
  82.   operands[1] = const0_rtx;
  83.   return AS2 (cmp%L0,%1,%0);
  84. }")
  85.  
  86. (define_expand "tstsi"
  87.   [(set (cc0)
  88.     (match_operand:SI 0 "nonimmediate_operand" ""))]
  89.   ""
  90.   "
  91. {
  92.   i386_compare_gen = gen_tstsi_1;
  93.   i386_compare_op0 = operands[0];
  94.   DONE;
  95. }")
  96.  
  97. (define_insn "tsthi_1"
  98.   [(set (cc0)
  99.     (match_operand:HI 0 "nonimmediate_operand" "rm"))]
  100.   ""
  101.   "*
  102. {
  103.   if (REG_P (operands[0]))
  104.     return AS2 (test%W0,%0,%0);
  105.  
  106.   operands[1] = const0_rtx;
  107.   return AS2 (cmp%W0,%1,%0);
  108. }")
  109.  
  110. (define_expand "tsthi"
  111.   [(set (cc0)
  112.     (match_operand:HI 0 "nonimmediate_operand" ""))]
  113.   ""
  114.   "
  115. {
  116.   i386_compare_gen = gen_tsthi_1;
  117.   i386_compare_op0 = operands[0];
  118.   DONE;
  119. }")
  120.  
  121. (define_insn "tstqi_1"
  122.   [(set (cc0)
  123.     (match_operand:QI 0 "nonimmediate_operand" "qm"))]
  124.   ""
  125.   "*
  126. {
  127.   if (REG_P (operands[0]))
  128.     return AS2 (test%B0,%0,%0);
  129.  
  130.   operands[1] = const0_rtx;
  131.   return AS2 (cmp%B0,%1,%0);
  132. }")
  133.  
  134. (define_expand "tstqi"
  135.   [(set (cc0)
  136.     (match_operand:QI 0 "nonimmediate_operand" ""))]
  137.   ""
  138.   "
  139. {
  140.   i386_compare_gen = gen_tstqi_1;
  141.   i386_compare_op0 = operands[0];
  142.   DONE;
  143. }")
  144.  
  145. (define_insn "tstsf_cc"
  146.   [(set (cc0)
  147.     (match_operand:SF 0 "register_operand" "f"))
  148.    (clobber (match_scratch:HI 1 "=a"))]
  149.   "TARGET_80387 && ! TARGET_IEEE_FP"
  150.   "*
  151. {
  152.   if (! STACK_TOP_P (operands[0]))
  153.     abort ();
  154.  
  155.   output_asm_insn (\"ftst\", operands);
  156.  
  157.   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  158.     output_asm_insn (AS1 (fstp,%y0), operands);
  159.  
  160.   return output_fp_cc0_set (insn);
  161. }")
  162.  
  163. ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
  164. ;; isn't IEEE compliant.
  165.  
  166. (define_expand "tstsf"
  167.   [(parallel [(set (cc0)
  168.            (match_operand:SF 0 "register_operand" ""))
  169.           (clobber (match_scratch:HI 1 ""))])]
  170.   "TARGET_80387 && ! TARGET_IEEE_FP"
  171.   "
  172. {
  173.   i386_compare_gen = gen_tstsf_cc;
  174.   i386_compare_op0 = operands[0];
  175.   DONE;
  176. }")
  177.  
  178. (define_insn "tstdf_cc"
  179.   [(set (cc0)
  180.     (match_operand:DF 0 "register_operand" "f"))
  181.    (clobber (match_scratch:HI 1 "=a"))]
  182.   "TARGET_80387 && ! TARGET_IEEE_FP"
  183.   "*
  184. {
  185.   if (! STACK_TOP_P (operands[0]))
  186.     abort ();
  187.  
  188.   output_asm_insn (\"ftst\", operands);
  189.  
  190.   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  191.     output_asm_insn (AS1 (fstp,%y0), operands);
  192.  
  193.   return output_fp_cc0_set (insn);
  194. }")
  195.  
  196. ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
  197. ;; isn't IEEE compliant.
  198.  
  199. (define_expand "tstdf"
  200.   [(parallel [(set (cc0)
  201.            (match_operand:DF 0 "register_operand" ""))
  202.           (clobber (match_scratch:HI 1 ""))])]
  203.   "TARGET_80387 && ! TARGET_IEEE_FP"
  204.   "
  205. {
  206.   i386_compare_gen = gen_tstdf_cc;
  207.   i386_compare_op0 = operands[0];
  208.   DONE;
  209. }")
  210.  
  211. (define_insn "tstxf_cc"
  212.   [(set (cc0)
  213.     (match_operand:XF 0 "register_operand" "f"))
  214.    (clobber (match_scratch:HI 1 "=a"))]
  215.   "TARGET_80387 && ! TARGET_IEEE_FP"
  216.   "*
  217. {
  218.   if (! STACK_TOP_P (operands[0]))
  219.     abort ();
  220.  
  221.   output_asm_insn (\"ftst\", operands);
  222.  
  223.   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  224.     output_asm_insn (AS1 (fstp,%y0), operands);
  225.  
  226.   return output_fp_cc0_set (insn);
  227. }")
  228.  
  229. ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
  230. ;; isn't IEEE compliant.
  231.  
  232. (define_expand "tstxf"
  233.   [(parallel [(set (cc0)
  234.            (match_operand:XF 0 "register_operand" ""))
  235.           (clobber (match_scratch:HI 1 ""))])]
  236.   "TARGET_80387 && ! TARGET_IEEE_FP"
  237.   "
  238. {
  239.   i386_compare_gen = gen_tstxf_cc;
  240.   i386_compare_op0 = operands[0];
  241.   DONE;
  242. }")
  243.  
  244. ;;- compare instructions.  See comments above tstM patterns about
  245. ;;  expansion of these insns.
  246.  
  247. (define_insn "cmpsi_1"
  248.   [(set (cc0)
  249.     (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
  250.          (match_operand:SI 1 "general_operand" "ri,mr")))]
  251.   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
  252.   "*
  253. {
  254.   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
  255.     {
  256.       cc_status.flags |= CC_REVERSED;
  257.       return AS2 (cmp%L0,%0,%1);
  258.     }
  259.   return AS2 (cmp%L0,%1,%0);
  260. }")
  261.  
  262. (define_expand "cmpsi"
  263.   [(set (cc0)
  264.     (compare (match_operand:SI 0 "nonimmediate_operand" "")
  265.          (match_operand:SI 1 "general_operand" "")))]
  266.   ""
  267.   "
  268. {
  269.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  270.     operands[0] = force_reg (SImode, operands[0]);
  271.  
  272.   i386_compare_gen = gen_cmpsi_1;
  273.   i386_compare_op0 = operands[0];
  274.   i386_compare_op1 = operands[1];
  275.   DONE;
  276. }")
  277.  
  278. (define_insn "cmphi_1"
  279.   [(set (cc0)
  280.     (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
  281.          (match_operand:HI 1 "general_operand" "ri,mr")))]
  282.   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
  283.   "*
  284. {
  285.   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
  286.     {
  287.       cc_status.flags |= CC_REVERSED;
  288.       return AS2 (cmp%W0,%0,%1);
  289.     }
  290.   return AS2 (cmp%W0,%1,%0);
  291. }")
  292.  
  293. (define_expand "cmphi"
  294.   [(set (cc0)
  295.     (compare (match_operand:HI 0 "nonimmediate_operand" "")
  296.          (match_operand:HI 1 "general_operand" "")))]
  297.   ""
  298.   "
  299. {
  300.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  301.     operands[0] = force_reg (HImode, operands[0]);
  302.  
  303.   i386_compare_gen = gen_cmphi_1;
  304.   i386_compare_op0 = operands[0];
  305.   i386_compare_op1 = operands[1];
  306.   DONE;
  307. }")
  308.  
  309. (define_insn "cmpqi_1"
  310.   [(set (cc0)
  311.     (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
  312.          (match_operand:QI 1 "general_operand" "qm,nq")))]
  313.   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
  314.   "*
  315. {
  316.   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
  317.     {
  318.       cc_status.flags |= CC_REVERSED;
  319.       return AS2 (cmp%B0,%0,%1);
  320.     }
  321.   return AS2 (cmp%B0,%1,%0);
  322. }")
  323.  
  324. (define_expand "cmpqi"
  325.   [(set (cc0)
  326.     (compare (match_operand:QI 0 "nonimmediate_operand" "")
  327.          (match_operand:QI 1 "general_operand" "")))]
  328.   ""
  329.   "
  330. {
  331.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  332.     operands[0] = force_reg (QImode, operands[0]);
  333.  
  334.   i386_compare_gen = gen_cmpqi_1;
  335.   i386_compare_op0 = operands[0];
  336.   i386_compare_op1 = operands[1];
  337.   DONE;
  338. }")
  339.  
  340. ;; These implement float point compares.  For each of DFmode and
  341. ;; SFmode, there is the normal insn, and an insn where the second operand
  342. ;; is converted to the desired mode.
  343.  
  344. (define_insn ""
  345.   [(set (cc0)
  346.     (match_operator 2 "VOIDmode_compare_op"
  347.             [(match_operand:XF 0 "nonimmediate_operand" "f")
  348.              (match_operand:XF 1 "nonimmediate_operand" "f")]))
  349.    (clobber (match_scratch:HI 3 "=a"))]
  350.   "TARGET_80387
  351.    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  352.   "* return output_float_compare (insn, operands);")
  353.  
  354. (define_insn ""
  355.   [(set (cc0)
  356.     (match_operator 2 "VOIDmode_compare_op"
  357.             [(match_operand:XF 0 "register_operand" "f")
  358.              (float:XF
  359.               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  360.    (clobber (match_scratch:HI 3 "=a"))]
  361.   "TARGET_80387"
  362.   "* return output_float_compare (insn, operands);")
  363.  
  364. (define_insn ""
  365.   [(set (cc0)
  366.     (match_operator 2 "VOIDmode_compare_op"
  367.             [(float:XF
  368.               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  369.              (match_operand:XF 1 "register_operand" "f")]))
  370.    (clobber (match_scratch:HI 3 "=a"))]
  371.   "TARGET_80387"
  372.   "* return output_float_compare (insn, operands);")
  373.  
  374. (define_insn ""
  375.   [(set (cc0)
  376.     (match_operator 2 "VOIDmode_compare_op"
  377.             [(match_operand:XF 0 "register_operand" "f")
  378.              (float_extend:XF
  379.               (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
  380.    (clobber (match_scratch:HI 3 "=a"))]
  381.   "TARGET_80387"
  382.   "* return output_float_compare (insn, operands);")
  383.  
  384. (define_insn ""
  385.   [(set (cc0)
  386.     (match_operator 2 "VOIDmode_compare_op"
  387.             [(match_operand:XF 0 "register_operand" "f")
  388.              (float_extend:XF
  389.               (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
  390.    (clobber (match_scratch:HI 3 "=a"))]
  391.   "TARGET_80387"
  392.   "* return output_float_compare (insn, operands);")
  393.  
  394. (define_insn ""
  395.   [(set (cc0)
  396.     (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
  397.             (match_operand:XF 1 "register_operand" "f")))
  398.    (clobber (match_scratch:HI 2 "=a"))]
  399.   "TARGET_80387"
  400.   "* return output_float_compare (insn, operands);")
  401.  
  402. (define_insn ""
  403.   [(set (cc0)
  404.     (match_operator 2 "VOIDmode_compare_op"
  405.             [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
  406.              (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
  407.    (clobber (match_scratch:HI 3 "=a,a"))]
  408.   "TARGET_80387
  409.    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  410.   "* return output_float_compare (insn, operands);")
  411.  
  412. (define_insn ""
  413.   [(set (cc0)
  414.     (match_operator 2 "VOIDmode_compare_op"
  415.             [(match_operand:DF 0 "register_operand" "f")
  416.              (float:DF
  417.               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  418.    (clobber (match_scratch:HI 3 "=a"))]
  419.   "TARGET_80387"
  420.   "* return output_float_compare (insn, operands);")
  421.  
  422. (define_insn ""
  423.   [(set (cc0)
  424.     (match_operator 2 "VOIDmode_compare_op"
  425.             [(float:DF
  426.               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  427.              (match_operand:DF 1 "register_operand" "f")]))
  428.    (clobber (match_scratch:HI 3 "=a"))]
  429.   "TARGET_80387"
  430.   "* return output_float_compare (insn, operands);")
  431.  
  432. (define_insn ""
  433.   [(set (cc0)
  434.     (match_operator 2 "VOIDmode_compare_op"
  435.             [(match_operand:DF 0 "register_operand" "f")
  436.              (float_extend:DF
  437.               (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
  438.    (clobber (match_scratch:HI 3 "=a"))]
  439.   "TARGET_80387"
  440.   "* return output_float_compare (insn, operands);")
  441.  
  442. (define_insn ""
  443.   [(set (cc0)
  444.     (match_operator 2 "VOIDmode_compare_op"
  445.             [(float_extend:DF
  446.               (match_operand:SF 0 "nonimmediate_operand" "fm"))
  447.              (match_operand:DF 1 "register_operand" "f")]))
  448.    (clobber (match_scratch:HI 3 "=a"))]
  449.   "TARGET_80387"
  450.   "* return output_float_compare (insn, operands);")
  451.  
  452. (define_insn ""
  453.   [(set (cc0)
  454.     (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
  455.             (match_operand:DF 1 "register_operand" "f")))
  456.    (clobber (match_scratch:HI 2 "=a"))]
  457.   "TARGET_80387"
  458.   "* return output_float_compare (insn, operands);")
  459.  
  460. ;; These two insns will never be generated by combine due to the mode of
  461. ;; the COMPARE.
  462. ;(define_insn ""
  463. ;  [(set (cc0)
  464. ;    (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
  465. ;            (float_extend:DF
  466. ;             (match_operand:SF 1 "register_operand" "f"))))
  467. ;   (clobber (match_scratch:HI 2 "=a"))]
  468. ;  "TARGET_80387"
  469. ;  "* return output_float_compare (insn, operands);")
  470. ;
  471. ;(define_insn ""
  472. ;  [(set (cc0)
  473. ;    (compare:CCFPEQ (float_extend:DF
  474. ;             (match_operand:SF 0 "register_operand" "f"))
  475. ;            (match_operand:DF 1 "register_operand" "f")))
  476. ;   (clobber (match_scratch:HI 2 "=a"))]
  477. ;  "TARGET_80387"
  478. ;  "* return output_float_compare (insn, operands);")
  479.  
  480. (define_insn "cmpsf_cc_1"
  481.   [(set (cc0)
  482.     (match_operator 2 "VOIDmode_compare_op"
  483.             [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
  484.              (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
  485.    (clobber (match_scratch:HI 3 "=a,a"))]
  486.   "TARGET_80387
  487.    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  488.   "* return output_float_compare (insn, operands);")
  489.  
  490. (define_insn ""
  491.   [(set (cc0)
  492.     (match_operator 2 "VOIDmode_compare_op"
  493.             [(match_operand:SF 0 "register_operand" "f")
  494.              (float:SF
  495.               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  496.    (clobber (match_scratch:HI 3 "=a"))]
  497.   "TARGET_80387"
  498.   "* return output_float_compare (insn, operands);")
  499.  
  500. (define_insn ""
  501.   [(set (cc0)
  502.     (match_operator 2 "VOIDmode_compare_op"
  503.             [(float:SF
  504.               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  505.              (match_operand:SF 1 "register_operand" "f")]))
  506.    (clobber (match_scratch:HI 3 "=a"))]
  507.   "TARGET_80387"
  508.   "* return output_float_compare (insn, operands);")
  509.  
  510. (define_insn ""
  511.   [(set (cc0)
  512.     (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
  513.             (match_operand:SF 1 "register_operand" "f")))
  514.    (clobber (match_scratch:HI 2 "=a"))]
  515.   "TARGET_80387"
  516.   "* return output_float_compare (insn, operands);")
  517.  
  518. (define_expand "cmpxf"
  519.   [(set (cc0)
  520.     (compare (match_operand:XF 0 "register_operand" "")
  521.          (match_operand:XF 1 "nonimmediate_operand" "")))]
  522.   "TARGET_80387"
  523.   "
  524. {
  525.   i386_compare_gen = gen_cmpxf_cc;
  526.   i386_compare_gen_eq = gen_cmpxf_ccfpeq;
  527.   i386_compare_op0 = operands[0];
  528.   i386_compare_op1 = operands[1];
  529.   DONE;
  530. }")
  531.  
  532. (define_expand "cmpdf"
  533.   [(set (cc0)
  534.     (compare (match_operand:DF 0 "register_operand" "")
  535.          (match_operand:DF 1 "nonimmediate_operand" "")))]
  536.   "TARGET_80387"
  537.   "
  538. {
  539.   i386_compare_gen = gen_cmpdf_cc;
  540.   i386_compare_gen_eq = gen_cmpdf_ccfpeq;
  541.   i386_compare_op0 = operands[0];
  542.   i386_compare_op1 = operands[1];
  543.   DONE;
  544. }")
  545.  
  546. (define_expand "cmpsf"
  547.   [(set (cc0)
  548.     (compare (match_operand:SF 0 "register_operand" "")
  549.          (match_operand:SF 1 "nonimmediate_operand" "")))]
  550.   "TARGET_80387"
  551.   "
  552. {
  553.   i386_compare_gen = gen_cmpsf_cc;
  554.   i386_compare_gen_eq = gen_cmpsf_ccfpeq;
  555.   i386_compare_op0 = operands[0];
  556.   i386_compare_op1 = operands[1];
  557.   DONE;
  558. }")
  559.  
  560. (define_expand "cmpxf_cc"
  561.   [(parallel [(set (cc0)
  562.            (compare (match_operand:XF 0 "register_operand" "")
  563.                 (match_operand:XF 1 "register_operand" "")))
  564.           (clobber (match_scratch:HI 2 ""))])]
  565.   "TARGET_80387"
  566.   "")
  567.  
  568. (define_expand "cmpxf_ccfpeq"
  569.   [(parallel [(set (cc0)
  570.            (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
  571.                    (match_operand:XF 1 "register_operand" "")))
  572.           (clobber (match_scratch:HI 2 ""))])]
  573.   "TARGET_80387"
  574.   "
  575. {
  576.   if (! register_operand (operands[1], XFmode))
  577.     operands[1] = copy_to_mode_reg (XFmode, operands[1]);
  578. }")
  579.  
  580. (define_expand "cmpdf_cc"
  581.   [(parallel [(set (cc0)
  582.            (compare (match_operand:DF 0 "register_operand" "")
  583.                 (match_operand:DF 1 "register_operand" "")))
  584.           (clobber (match_scratch:HI 2 ""))])]
  585.   "TARGET_80387"
  586.   "")
  587.  
  588. (define_expand "cmpdf_ccfpeq"
  589.   [(parallel [(set (cc0)
  590.            (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
  591.                    (match_operand:DF 1 "register_operand" "")))
  592.           (clobber (match_scratch:HI 2 ""))])]
  593.   "TARGET_80387"
  594.   "
  595. {
  596.   if (! register_operand (operands[1], DFmode))
  597.     operands[1] = copy_to_mode_reg (DFmode, operands[1]);
  598. }")
  599.  
  600. (define_expand "cmpsf_cc"
  601.   [(parallel [(set (cc0)
  602.            (compare (match_operand:SF 0 "register_operand" "")
  603.                 (match_operand:SF 1 "register_operand" "")))
  604.           (clobber (match_scratch:HI 2 ""))])]
  605.   "TARGET_80387"
  606.   "")
  607.  
  608. (define_expand "cmpsf_ccfpeq"
  609.   [(parallel [(set (cc0)
  610.            (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
  611.                    (match_operand:SF 1 "register_operand" "")))
  612.           (clobber (match_scratch:HI 2 ""))])]
  613.   "TARGET_80387"
  614.   "
  615. {
  616.   if (! register_operand (operands[1], SFmode))
  617.     operands[1] = copy_to_mode_reg (SFmode, operands[1]);
  618. }")
  619.  
  620. ;; logical compare
  621.  
  622. (define_insn ""
  623.   [(set (cc0)
  624.     (and:SI (match_operand:SI 0 "general_operand" "%ro")
  625.         (match_operand:SI 1 "general_operand" "ri")))]
  626.   ""
  627.   "*
  628. {
  629.   /* For small integers, we may actually use testb. */
  630.   if (GET_CODE (operands[1]) == CONST_INT
  631.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
  632.       && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
  633.     {
  634.       /* We may set the sign bit spuriously.  */
  635.  
  636.       if ((INTVAL (operands[1]) & ~0xff) == 0)
  637.         {
  638.       cc_status.flags |= CC_NOT_NEGATIVE;
  639.       return AS2 (test%B0,%1,%b0);
  640.     }
  641.  
  642.       if ((INTVAL (operands[1]) & ~0xff00) == 0)
  643.         {
  644.       cc_status.flags |= CC_NOT_NEGATIVE;
  645.       operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
  646.  
  647.       if (QI_REG_P (operands[0]))
  648.         return AS2 (test%B0,%1,%h0);
  649.       else
  650.         {
  651.           operands[0] = adj_offsettable_operand (operands[0], 1);
  652.           return AS2 (test%B0,%1,%b0);
  653.         }
  654.     }
  655.  
  656.       if (GET_CODE (operands[0]) == MEM
  657.       && (INTVAL (operands[1]) & ~0xff0000) == 0)
  658.         {
  659.       cc_status.flags |= CC_NOT_NEGATIVE;
  660.       operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
  661.       operands[0] = adj_offsettable_operand (operands[0], 2);
  662.       return AS2 (test%B0,%1,%b0);
  663.     }
  664.  
  665.       if (GET_CODE (operands[0]) == MEM
  666.       && (INTVAL (operands[1]) & ~0xff000000) == 0)
  667.         {
  668.       operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
  669.       operands[0] = adj_offsettable_operand (operands[0], 3);
  670.       return AS2 (test%B0,%1,%b0);
  671.     }
  672.     }
  673.  
  674.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  675.     return AS2 (test%L0,%1,%0);
  676.  
  677.   return AS2 (test%L1,%0,%1);
  678. }")
  679.  
  680. (define_insn ""
  681.   [(set (cc0)
  682.     (and:HI (match_operand:HI 0 "general_operand" "%ro")
  683.         (match_operand:HI 1 "general_operand" "ri")))]
  684.   ""
  685.   "*
  686. {
  687.   if (GET_CODE (operands[1]) == CONST_INT
  688.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
  689.       && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
  690.     {
  691.       if ((INTVAL (operands[1]) & 0xff00) == 0)
  692.     {
  693.       /* ??? This might not be necessary. */
  694.       if (INTVAL (operands[1]) & 0xffff0000)
  695.         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
  696.  
  697.       /* We may set the sign bit spuriously.  */
  698.       cc_status.flags |= CC_NOT_NEGATIVE;
  699.       return AS2 (test%B0,%1,%b0);
  700.     }
  701.  
  702.       if ((INTVAL (operands[1]) & 0xff) == 0)
  703.         {
  704.       operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
  705.  
  706.       if (QI_REG_P (operands[0]))
  707.         return AS2 (test%B0,%1,%h0);
  708.       else
  709.         {
  710.           operands[0] = adj_offsettable_operand (operands[0], 1);
  711.           return AS2 (test%B0,%1,%b0);
  712.         }
  713.     }
  714.     }
  715.  
  716.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  717.     return AS2 (test%W0,%1,%0);
  718.  
  719.   return AS2 (test%W1,%0,%1);
  720. }")
  721.  
  722. (define_insn ""
  723.   [(set (cc0)
  724.     (and:QI (match_operand:QI 0 "general_operand" "%qm")
  725.         (match_operand:QI 1 "general_operand" "qi")))]
  726.   ""
  727.   "*
  728. {
  729.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  730.     return AS2 (test%B0,%1,%0);
  731.  
  732.   return AS2 (test%B1,%0,%1);
  733. }")
  734.  
  735. ;; move instructions.
  736. ;; There is one for each machine mode,
  737. ;; and each is preceded by a corresponding push-insn pattern
  738. ;; (since pushes are not general_operands on the 386).
  739.  
  740. (define_insn ""
  741.   [(set (match_operand:SI 0 "push_operand" "=<")
  742.     (match_operand:SI 1 "general_operand" "g"))]
  743.   "TARGET_386"
  744.   "push%L0 %1")
  745.  
  746. ;; On a 486, it is faster to move MEM to a REG and then push, rather than
  747. ;; push MEM directly.
  748.  
  749. (define_insn ""
  750.   [(set (match_operand:SI 0 "push_operand" "=<")
  751.     (match_operand:SI 1 "nonmemory_operand" "ri"))]
  752.   "!TARGET_386 && TARGET_MOVE"
  753.   "push%L0 %1")
  754.  
  755. (define_insn ""
  756.   [(set (match_operand:SI 0 "push_operand" "=<")
  757.     (match_operand:SI 1 "general_operand" "ri"))]
  758.   "!TARGET_386 && !TARGET_MOVE"
  759.   "push%L0 %1")
  760.  
  761. ;; General case of fullword move.
  762.  
  763. ;; If generating PIC code and operands[1] is a symbolic CONST, emit a
  764. ;; move to get the address of the symbolic object from the GOT.
  765.  
  766. (define_expand "movsi"
  767.   [(set (match_operand:SI 0 "general_operand" "")
  768.     (match_operand:SI 1 "general_operand" ""))]
  769.   ""
  770.   "
  771. {
  772.   extern int flag_pic;
  773.  
  774.   if (flag_pic && SYMBOLIC_CONST (operands[1]))
  775.     emit_pic_move (operands, SImode);
  776.  
  777.   /* Don't generate memory->memory moves, go through a register */
  778.   else if (TARGET_MOVE
  779.        && (reload_in_progress | reload_completed) == 0
  780.        && GET_CODE (operands[0]) == MEM
  781.        && GET_CODE (operands[1]) == MEM)
  782.     {
  783.       operands[1] = force_reg (SImode, operands[1]);
  784.     }
  785. }")
  786.  
  787. ;; On i486, incl reg is faster than movl $1,reg.
  788.  
  789. (define_insn ""
  790.   [(set (match_operand:SI 0 "general_operand" "=g,r")
  791.     (match_operand:SI 1 "general_operand" "ri,m"))]
  792.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  793.   "*
  794. {
  795.   rtx link;
  796.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  797.     return AS2 (xor%L0,%0,%0);
  798.  
  799.   if (operands[1] == const1_rtx
  800.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  801.       /* Make sure the insn that stored the 0 is still present.  */
  802.       && ! INSN_DELETED_P (XEXP (link, 0))
  803.       && GET_CODE (XEXP (link, 0)) != NOTE
  804.       /* Make sure cross jumping didn't happen here.  */
  805.       && no_labels_between_p (XEXP (link, 0), insn)
  806.       /* Make sure the reg hasn't been clobbered.  */
  807.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  808.     /* Fastest way to change a 0 to a 1.  */
  809.     return AS1 (inc%L0,%0);
  810.  
  811.   if (flag_pic && SYMBOLIC_CONST (operands[1]))
  812.     return AS2 (lea%L0,%a1,%0);
  813.  
  814.   return AS2 (mov%L0,%1,%0);
  815. }")
  816.  
  817. (define_insn ""
  818.   [(set (match_operand:HI 0 "push_operand" "=<")
  819.     (match_operand:HI 1 "general_operand" "g"))]
  820.   "TARGET_386"
  821.   "push%W0 %1")
  822.  
  823. (define_insn ""
  824.   [(set (match_operand:HI 0 "push_operand" "=<")
  825.     (match_operand:HI 1 "nonmemory_operand" "ri"))]
  826.   "!TARGET_386 && TARGET_MOVE"
  827.   "push%W0 %1")
  828.  
  829. (define_insn ""
  830.   [(set (match_operand:HI 0 "push_operand" "=<")
  831.     (match_operand:HI 1 "general_operand" "ri"))]
  832.   "!TARGET_386 && !TARGET_MOVE"
  833.   "push%W0 %1")
  834.  
  835. ;; On i486, an incl and movl are both faster than incw and movw.
  836.  
  837. (define_expand "movhi"
  838.   [(set (match_operand:HI 0 "general_operand" "")
  839.     (match_operand:HI 1 "general_operand" ""))]
  840.   ""
  841.   "
  842. {
  843.   /* Don't generate memory->memory moves, go through a register */
  844.   if (TARGET_MOVE
  845.       && (reload_in_progress | reload_completed) == 0
  846.       && GET_CODE (operands[0]) == MEM
  847.       && GET_CODE (operands[1]) == MEM)
  848.     {
  849.       operands[1] = force_reg (HImode, operands[1]);
  850.     }
  851. }")
  852.  
  853. (define_insn ""
  854.   [(set (match_operand:HI 0 "general_operand" "=g,r")
  855.     (match_operand:HI 1 "general_operand" "ri,m"))]
  856.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  857.   "*
  858. {
  859.   rtx link;
  860.   if (REG_P (operands[0]) && operands[1] == const0_rtx)
  861.     return AS2 (xor%L0,%k0,%k0);
  862.  
  863.   if (REG_P (operands[0]) && operands[1] == const1_rtx 
  864.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  865.       /* Make sure the insn that stored the 0 is still present.  */
  866.       && ! INSN_DELETED_P (XEXP (link, 0))
  867.       && GET_CODE (XEXP (link, 0)) != NOTE
  868.       /* Make sure cross jumping didn't happen here.  */
  869.       && no_labels_between_p (XEXP (link, 0), insn)
  870.       /* Make sure the reg hasn't been clobbered.  */
  871.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  872.     /* Fastest way to change a 0 to a 1.  */
  873.     return AS1 (inc%L0,%k0);
  874.  
  875.   if (REG_P (operands[0]))
  876.     {
  877.       if (REG_P (operands[1]))
  878.     return AS2 (mov%L0,%k1,%k0);
  879.       else if (CONSTANT_P (operands[1]))
  880.     return AS2 (mov%L0,%1,%k0);
  881.     }
  882.  
  883.   return AS2 (mov%W0,%1,%0);
  884. }")
  885.  
  886. (define_expand "movstricthi"
  887.   [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
  888.     (match_operand:HI 1 "general_operand" ""))]
  889.   ""
  890.   "
  891. {
  892.   /* Don't generate memory->memory moves, go through a register */
  893.   if (TARGET_MOVE
  894.       && (reload_in_progress | reload_completed) == 0
  895.       && GET_CODE (operands[0]) == MEM
  896.       && GET_CODE (operands[1]) == MEM)
  897.     {
  898.       operands[1] = force_reg (HImode, operands[1]);
  899.     }
  900. }")
  901.  
  902. (define_insn ""
  903.   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
  904.     (match_operand:HI 1 "general_operand" "ri,m"))]
  905.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  906.   "*
  907. {
  908.   rtx link;
  909.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  910.     return AS2 (xor%W0,%0,%0);
  911.  
  912.   if (operands[1] == const1_rtx
  913.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  914.       /* Make sure the insn that stored the 0 is still present.  */
  915.       && ! INSN_DELETED_P (XEXP (link, 0))
  916.       && GET_CODE (XEXP (link, 0)) != NOTE
  917.       /* Make sure cross jumping didn't happen here.  */
  918.       && no_labels_between_p (XEXP (link, 0), insn)
  919.       /* Make sure the reg hasn't been clobbered.  */
  920.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  921.     /* Fastest way to change a 0 to a 1.  */
  922.     return AS1 (inc%W0,%0);
  923.  
  924.   return AS2 (mov%W0,%1,%0);
  925. }")
  926.  
  927. ;; emit_push_insn when it calls move_by_pieces
  928. ;; requires an insn to "push a byte".
  929. ;; But actually we use pushw, which has the effect of rounding
  930. ;; the amount pushed up to a halfword.
  931. (define_insn ""
  932.   [(set (match_operand:QI 0 "push_operand" "=<")
  933.     (match_operand:QI 1 "immediate_operand" "n"))]
  934.   ""
  935.   "* return AS1 (push%W0,%1);")
  936.  
  937. (define_insn ""
  938.   [(set (match_operand:QI 0 "push_operand" "=<")
  939.     (match_operand:QI 1 "nonimmediate_operand" "q"))]
  940.   "!TARGET_MOVE"
  941.   "*
  942. {
  943.   operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
  944.   return AS1 (push%W0,%1);
  945. }")
  946.  
  947. (define_insn ""
  948.   [(set (match_operand:QI 0 "push_operand" "=<")
  949.     (match_operand:QI 1 "register_operand" "q"))]
  950.   "TARGET_MOVE"
  951.   "*
  952. {
  953.   operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
  954.   return AS1 (push%W0,%1);
  955. }")
  956.  
  957. ;; On i486, incb reg is faster than movb $1,reg.
  958.  
  959. ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
  960. ;; or writes %ah, %bh, %ch, %dh.
  961.  
  962. (define_expand "movqi"
  963.   [(set (match_operand:QI 0 "general_operand" "")
  964.     (match_operand:QI 1 "general_operand" ""))]
  965.   ""
  966.   "
  967. {
  968.   /* Don't generate memory->memory moves, go through a register */
  969.   if (TARGET_MOVE
  970.       && (reload_in_progress | reload_completed) == 0
  971.       && GET_CODE (operands[0]) == MEM
  972.       && GET_CODE (operands[1]) == MEM)
  973.     {
  974.       operands[1] = force_reg (QImode, operands[1]);
  975.     }
  976. }")
  977.  
  978. (define_insn ""
  979.   [(set (match_operand:QI 0 "general_operand" "=q,*r,qm")
  980.     (match_operand:QI 1 "general_operand" "*g,q,qn"))]
  981.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  982.   "*
  983. {
  984.   rtx link;
  985.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  986.     return AS2 (xor%B0,%0,%0);
  987.  
  988.   if (operands[1] == const1_rtx
  989.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  990.       /* Make sure the insn that stored the 0 is still present.  */
  991.       && ! INSN_DELETED_P (XEXP (link, 0))
  992.       && GET_CODE (XEXP (link, 0)) != NOTE
  993.       /* Make sure cross jumping didn't happen here.  */
  994.       && no_labels_between_p (XEXP (link, 0), insn)
  995.       /* Make sure the reg hasn't been clobbered.  */
  996.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  997.     /* Fastest way to change a 0 to a 1.  */
  998.     return AS1 (inc%B0,%0);
  999.  
  1000.   /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
  1001.   if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
  1002.     return (AS2 (mov%L0,%k1,%k0));
  1003.  
  1004.   return (AS2 (mov%B0,%1,%0));
  1005. }")
  1006.  
  1007. ;; If it becomes necessary to support movstrictqi into %esi or %edi,
  1008. ;; use the insn sequence:
  1009. ;;
  1010. ;;    shrdl $8,srcreg,dstreg
  1011. ;;    rorl $24,dstreg
  1012. ;;
  1013. ;; If operands[1] is a constant, then an andl/orl sequence would be
  1014. ;; faster.
  1015.  
  1016. (define_expand "movstrictqi"
  1017.   [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
  1018.     (match_operand:QI 1 "general_operand" ""))]
  1019.   ""
  1020.   "
  1021. {
  1022.   /* Don't generate memory->memory moves, go through a register */
  1023.   if (TARGET_MOVE
  1024.       && (reload_in_progress | reload_completed) == 0
  1025.       && GET_CODE (operands[0]) == MEM
  1026.       && GET_CODE (operands[1]) == MEM)
  1027.     {
  1028.       operands[1] = force_reg (QImode, operands[1]);
  1029.     }
  1030. }")
  1031.  
  1032. (define_insn ""
  1033.   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+qm,q"))
  1034.     (match_operand:QI 1 "general_operand" "*qn,m"))]
  1035.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  1036.   "*
  1037. {
  1038.   rtx link;
  1039.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  1040.     return AS2 (xor%B0,%0,%0);
  1041.  
  1042.   if (operands[1] == const1_rtx
  1043.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  1044.       /* Make sure the insn that stored the 0 is still present.  */
  1045.       && ! INSN_DELETED_P (XEXP (link, 0))
  1046.       && GET_CODE (XEXP (link, 0)) != NOTE
  1047.       /* Make sure cross jumping didn't happen here.  */
  1048.       && no_labels_between_p (XEXP (link, 0), insn)
  1049.       /* Make sure the reg hasn't been clobbered.  */
  1050.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  1051.     /* Fastest way to change a 0 to a 1.  */
  1052.     return AS1 (inc%B0,%0);
  1053.  
  1054.   /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
  1055.   if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
  1056.     {
  1057.       abort ();
  1058.       return (AS2 (mov%L0,%k1,%k0));
  1059.     }
  1060.  
  1061.   return AS2 (mov%B0,%1,%0);
  1062. }")
  1063.  
  1064. (define_expand "movsf"
  1065.   [(set (match_operand:SF 0 "general_operand" "")
  1066.     (match_operand:SF 1 "general_operand" ""))]
  1067.   ""
  1068.   "
  1069. {
  1070.   /* Special case memory->memory moves and pushes */
  1071.   if (TARGET_MOVE
  1072.       && (reload_in_progress | reload_completed) == 0
  1073.       && GET_CODE (operands[0]) == MEM
  1074.       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], SFmode)))
  1075.     {
  1076.       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], SFmode))
  1077.                         ? gen_movsf_push
  1078.                         : gen_movsf_mem;
  1079.  
  1080.       emit_insn ((*genfunc) (operands[0], operands[1]));
  1081.       DONE;
  1082.     }
  1083.  
  1084.   /* If we are loading a floating point constant that isn't 0 or 1 into a register,
  1085.      indicate we need the pic register loaded.  This could be optimized into stores
  1086.      of constants if the target eventually moves to memory, but better safe than
  1087.      sorry.  */
  1088.   if (flag_pic
  1089.       && GET_CODE (operands[0]) != MEM
  1090.       && GET_CODE (operands[1]) == CONST_DOUBLE
  1091.       && !standard_80387_constant_p (operands[1]))
  1092.     {
  1093.       current_function_uses_pic_offset_table = 1;
  1094.     }
  1095. }")
  1096.  
  1097. (define_insn "movsf_push_nomove"
  1098.   [(set (match_operand:SF 0 "push_operand" "=<,<")
  1099.     (match_operand:SF 1 "general_operand" "gF,f"))]
  1100.   "!TARGET_MOVE"
  1101.   "*
  1102. {
  1103.   if (STACK_REG_P (operands[1]))
  1104.     {
  1105.       rtx xops[3];
  1106.  
  1107.       if (! STACK_TOP_P (operands[1]))
  1108.         abort ();
  1109.  
  1110.       xops[0] = AT_SP (SFmode);
  1111.       xops[1] = GEN_INT (4);
  1112.       xops[2] = stack_pointer_rtx;
  1113.  
  1114.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1115.  
  1116.       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1117.         output_asm_insn (AS1 (fstp%S0,%0), xops);
  1118.       else
  1119.         output_asm_insn (AS1 (fst%S0,%0), xops);
  1120.       RET;
  1121.     }
  1122.   return AS1 (push%L1,%1);
  1123. }")
  1124.  
  1125. (define_insn "movsf_push"
  1126.   [(set (match_operand:SF 0 "push_operand" "=<,<,<,<")
  1127.     (match_operand:SF 1 "general_operand" "rF,f,m,m"))
  1128.    (clobber (match_scratch:SI 2 "=X,X,r,X"))]
  1129.   ""
  1130.   "*
  1131. {
  1132.   if (STACK_REG_P (operands[1]))
  1133.     {
  1134.       rtx xops[3];
  1135.  
  1136.       if (! STACK_TOP_P (operands[1]))
  1137.         abort ();
  1138.  
  1139.       xops[0] = AT_SP (SFmode);
  1140.       xops[1] = GEN_INT (4);
  1141.       xops[2] = stack_pointer_rtx;
  1142.  
  1143.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1144.  
  1145.       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1146.         output_asm_insn (AS1 (fstp%S0,%0), xops);
  1147.       else
  1148.         output_asm_insn (AS1 (fst%S0,%0), xops);
  1149.       RET;
  1150.     }
  1151.  
  1152.   else if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != REG)
  1153.     return AS1 (push%L1,%1);
  1154.  
  1155.   else
  1156.     {
  1157.       output_asm_insn (AS2 (mov%L2,%1,%2), operands);
  1158.       return AS1 (push%L2,%2);
  1159.     }
  1160. }")
  1161.  
  1162. ;; Special memory<->memory pattern that combine will recreate from the
  1163. ;; moves to pseudos.
  1164. (define_insn "movsf_mem"
  1165.   [(set (match_operand:SF 0 "memory_operand" "=m")
  1166.     (match_operand:SF 1 "memory_operand" "m"))
  1167.    (clobber (match_scratch:SI 2 "=&r"))]
  1168.   ""
  1169.   "*
  1170. {
  1171.   output_asm_insn (AS2 (mov%L2,%1,%2), operands);
  1172.   return AS2 (mov%L0,%2,%0);
  1173. }")
  1174.  
  1175. ;; For the purposes of regclass, prefer FLOAT_REGS.
  1176. (define_insn "movsf_normal"
  1177.   [(set (match_operand:SF 0 "general_operand" "=*rfm,*rf,f,!*rm")
  1178.     (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
  1179.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  1180.   "*
  1181. {
  1182.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1183.  
  1184.   /* First handle a `pop' insn or a `fld %st(0)' */
  1185.  
  1186.   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
  1187.     {
  1188.       if (stack_top_dies)
  1189.     return AS1 (fstp,%y0);
  1190.       else
  1191.         return AS1 (fld,%y0);
  1192.     }
  1193.  
  1194.   /* Handle a transfer between the 387 and a 386 register */
  1195.  
  1196.   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
  1197.     {
  1198.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1199.       RET;
  1200.     }
  1201.  
  1202.   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
  1203.     {
  1204.       output_to_reg (operands[0], stack_top_dies);
  1205.       RET;
  1206.     }
  1207.  
  1208.   /* Handle other kinds of writes from the 387 */
  1209.  
  1210.   if (STACK_TOP_P (operands[1]))
  1211.     {
  1212.       if (stack_top_dies)
  1213.     return AS1 (fstp%z0,%y0);
  1214.       else
  1215.         return AS1 (fst%z0,%y0);
  1216.     }
  1217.  
  1218.   /* Handle other kinds of reads to the 387 */
  1219.  
  1220.   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  1221.     return output_move_const_single (operands);
  1222.  
  1223.   if (STACK_TOP_P (operands[0]))
  1224.     return AS1 (fld%z1,%y1);
  1225.  
  1226.   /* Handle all SFmode moves not involving the 387 */
  1227.  
  1228.   return singlemove_string (operands);
  1229. }")
  1230.  
  1231. (define_insn "swapsf"
  1232.   [(set (match_operand:SF 0 "register_operand" "f")
  1233.     (match_operand:SF 1 "register_operand" "f"))
  1234.    (set (match_dup 1)
  1235.     (match_dup 0))]
  1236.   ""
  1237.   "*
  1238. {
  1239.   if (STACK_TOP_P (operands[0]))
  1240.     return AS1 (fxch,%1);
  1241.   else
  1242.     return AS1 (fxch,%0);
  1243. }")
  1244.  
  1245. (define_expand "movdf"
  1246.   [(set (match_operand:DF 0 "general_operand" "")
  1247.     (match_operand:DF 1 "general_operand" ""))]
  1248.   ""
  1249.   "
  1250. {
  1251.   /* Special case memory->memory moves and pushes */
  1252.   if (TARGET_MOVE
  1253.       && (reload_in_progress | reload_completed) == 0
  1254.       && GET_CODE (operands[0]) == MEM
  1255.       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], DFmode)))
  1256.     {
  1257.       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], DFmode))
  1258.                         ? gen_movdf_push
  1259.                         : gen_movdf_mem;
  1260.  
  1261.       emit_insn ((*genfunc) (operands[0], operands[1]));
  1262.       DONE;
  1263.     }
  1264.  
  1265.   /* If we are loading a floating point constant that isn't 0 or 1 into a register,
  1266.      indicate we need the pic register loaded.  This could be optimized into stores
  1267.      of constants if the target eventually moves to memory, but better safe than
  1268.      sorry.  */
  1269.   if (flag_pic
  1270.       && GET_CODE (operands[0]) != MEM
  1271.       && GET_CODE (operands[1]) == CONST_DOUBLE
  1272.       && !standard_80387_constant_p (operands[1]))
  1273.     {
  1274.       current_function_uses_pic_offset_table = 1;
  1275.     }
  1276. }")
  1277.  
  1278. (define_insn "movdf_push_nomove"
  1279.   [(set (match_operand:DF 0 "push_operand" "=<,<")
  1280.     (match_operand:DF 1 "general_operand" "gF,f"))]
  1281.   "!TARGET_MOVE"
  1282.   "*
  1283. {
  1284.   if (STACK_REG_P (operands[1]))
  1285.     {
  1286.       rtx xops[3];
  1287.  
  1288.       xops[0] = AT_SP (SFmode);
  1289.       xops[1] = GEN_INT (8);
  1290.       xops[2] = stack_pointer_rtx;
  1291.  
  1292.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1293.  
  1294.       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1295.         output_asm_insn (AS1 (fstp%Q0,%0), xops);
  1296.       else
  1297.         output_asm_insn (AS1 (fst%Q0,%0), xops);
  1298.  
  1299.       RET;
  1300.     }
  1301.   else
  1302.     return output_move_double (operands);
  1303. }")
  1304.  
  1305. (define_insn "movdf_push"
  1306.   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<")
  1307.     (match_operand:DF 1 "general_operand" "rF,f,o,o,o"))
  1308.    (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
  1309.    (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
  1310.   ""
  1311.   "*
  1312. {
  1313.   if (STACK_REG_P (operands[1]))
  1314.     {
  1315.       rtx xops[3];
  1316.  
  1317.       xops[0] = AT_SP (SFmode);
  1318.       xops[1] = GEN_INT (8);
  1319.       xops[2] = stack_pointer_rtx;
  1320.  
  1321.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1322.  
  1323.       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1324.         output_asm_insn (AS1 (fstp%Q0,%0), xops);
  1325.       else
  1326.         output_asm_insn (AS1 (fst%Q0,%0), xops);
  1327.  
  1328.       RET;
  1329.     }
  1330.  
  1331.   else if (GET_CODE (operands[1]) != MEM)
  1332.     return output_move_double (operands);
  1333.  
  1334.   else
  1335.     return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);
  1336. }")
  1337.  
  1338. (define_insn "movdf_mem"
  1339.   [(set (match_operand:DF 0 "memory_operand" "=o,o")
  1340.     (match_operand:DF 1 "memory_operand" "o,o"))
  1341.    (clobber (match_scratch:SI 2 "=&r,&r"))
  1342.    (clobber (match_scratch:SI 3 "=&r,X"))]
  1343.   ""
  1344.   "* return output_move_memory (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);")
  1345.  
  1346. ;; For the purposes of regclass, prefer FLOAT_REGS.
  1347. (define_insn "movdf_normal"
  1348.   [(set (match_operand:DF 0 "general_operand" "=f,fm,!*rf,!*rm")
  1349.     (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
  1350.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  1351.   "*
  1352. {
  1353.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1354.  
  1355.   /* First handle a `pop' insn or a `fld %st(0)' */
  1356.  
  1357.   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
  1358.     {
  1359.       if (stack_top_dies)
  1360.     return AS1 (fstp,%y0);
  1361.       else
  1362.         return AS1 (fld,%y0);
  1363.     }
  1364.  
  1365.   /* Handle a transfer between the 387 and a 386 register */
  1366.  
  1367.   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
  1368.     {
  1369.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1370.       RET;
  1371.     }
  1372.  
  1373.   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
  1374.     {
  1375.       output_to_reg (operands[0], stack_top_dies);
  1376.       RET;
  1377.     }
  1378.  
  1379.   /* Handle other kinds of writes from the 387 */
  1380.  
  1381.   if (STACK_TOP_P (operands[1]))
  1382.     {
  1383.       if (stack_top_dies)
  1384.     return AS1 (fstp%z0,%y0);
  1385.       else
  1386.         return AS1 (fst%z0,%y0);
  1387.     }
  1388.  
  1389.   /* Handle other kinds of reads to the 387 */
  1390.  
  1391.   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  1392.     return output_move_const_single (operands);
  1393.  
  1394.   if (STACK_TOP_P (operands[0]))
  1395.     return AS1 (fld%z1,%y1);
  1396.  
  1397.   /* Handle all DFmode moves not involving the 387 */
  1398.  
  1399.   return output_move_double (operands);
  1400. }")
  1401.  
  1402. (define_insn "swapdf"
  1403.   [(set (match_operand:DF 0 "register_operand" "f")
  1404.     (match_operand:DF 1 "register_operand" "f"))
  1405.    (set (match_dup 1)
  1406.     (match_dup 0))]
  1407.   ""
  1408.   "*
  1409. {
  1410.   if (STACK_TOP_P (operands[0]))
  1411.     return AS1 (fxch,%1);
  1412.   else
  1413.     return AS1 (fxch,%0);
  1414. }")
  1415.  
  1416. (define_expand "movxf"
  1417.   [(set (match_operand:XF 0 "general_operand" "")
  1418.     (match_operand:XF 1 "general_operand" ""))]
  1419.   ""
  1420.   "
  1421. {
  1422.   /* Special case memory->memory moves and pushes */
  1423.   if (TARGET_MOVE
  1424.       && (reload_in_progress | reload_completed) == 0
  1425.       && GET_CODE (operands[0]) == MEM
  1426.       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], XFmode)))
  1427.     {
  1428.       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], XFmode))
  1429.                         ? gen_movxf_push
  1430.                         : gen_movxf_mem;
  1431.  
  1432.       emit_insn ((*genfunc) (operands[0], operands[1]));
  1433.       DONE;
  1434.     }
  1435.  
  1436.   /* If we are loading a floating point constant that isn't 0 or 1 into a register,
  1437.      indicate we need the pic register loaded.  This could be optimized into stores
  1438.      of constants if the target eventually moves to memory, but better safe than
  1439.      sorry.  */
  1440.   if (flag_pic
  1441.       && GET_CODE (operands[0]) != MEM
  1442.       && GET_CODE (operands[1]) == CONST_DOUBLE
  1443.       && !standard_80387_constant_p (operands[1]))
  1444.     {
  1445.       current_function_uses_pic_offset_table = 1;
  1446.     }
  1447. }")
  1448.  
  1449.  
  1450. (define_insn "movxf_push_nomove"
  1451.   [(set (match_operand:XF 0 "push_operand" "=<,<")
  1452.      (match_operand:XF 1 "general_operand" "gF,f"))]
  1453.   "!TARGET_MOVE"
  1454.   "*
  1455. {
  1456.   if (STACK_REG_P (operands[1]))
  1457.     {
  1458.       rtx xops[3];
  1459.  
  1460.       xops[0] = AT_SP (SFmode);
  1461.       xops[1] = GEN_INT (12);
  1462.       xops[2] = stack_pointer_rtx;
  1463.  
  1464.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1465.       output_asm_insn (AS1 (fstp%T0,%0), xops);
  1466.       if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1467.     output_asm_insn (AS1 (fld%T0,%0), xops);
  1468.  
  1469.       RET;
  1470.     }
  1471.   else
  1472.     return output_move_double (operands);
  1473.  }")
  1474.  
  1475. (define_insn "movxf_push"
  1476.   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
  1477.      (match_operand:XF 1 "general_operand" "rF,f,o,o,o"))
  1478.    (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
  1479.    (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
  1480.   ""
  1481.   "*
  1482. {
  1483.   if (STACK_REG_P (operands[1]))
  1484.     {
  1485.       rtx xops[3];
  1486.  
  1487.       xops[0] = AT_SP (SFmode);
  1488.       xops[1] = GEN_INT (12);
  1489.       xops[2] = stack_pointer_rtx;
  1490.  
  1491.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1492.       output_asm_insn (AS1 (fstp%T0,%0), xops);
  1493.       if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1494.     output_asm_insn (AS1 (fld%T0,%0), xops);
  1495.  
  1496.       RET;
  1497.     }
  1498.  
  1499.   else if (GET_CODE (operands[1]) != MEM
  1500.        || GET_CODE (operands[2]) != REG)
  1501.     return output_move_double (operands);
  1502.  
  1503.   else
  1504.     return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);
  1505. }")
  1506.  
  1507. (define_insn "movxf_mem"
  1508.   [(set (match_operand:XF 0 "memory_operand" "=o,o")
  1509.     (match_operand:XF 1 "memory_operand" "o,o"))
  1510.    (clobber (match_scratch:SI 2 "=&r,&r"))
  1511.    (clobber (match_scratch:SI 3 "=&r,X"))]
  1512.   ""
  1513.   "* return output_move_memory (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);")
  1514.  
  1515. (define_insn "movxf_normal"
  1516.   [(set (match_operand:XF 0 "general_operand" "=f,fm,!*rf,!*rm")
  1517.     (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
  1518.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  1519.   "*
  1520. {
  1521.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1522.  
  1523.   /* First handle a `pop' insn or a `fld %st(0)' */
  1524.  
  1525.   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
  1526.     {
  1527.       if (stack_top_dies)
  1528.     return AS1 (fstp,%y0);
  1529.       else
  1530.         return AS1 (fld,%y0);
  1531.     }
  1532.  
  1533.   /* Handle a transfer between the 387 and a 386 register */
  1534.  
  1535.   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
  1536.     {
  1537.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1538.       RET;
  1539.     }
  1540.  
  1541.   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
  1542.     {
  1543.       output_to_reg (operands[0], stack_top_dies);
  1544.       RET;
  1545.     }
  1546.  
  1547.   /* Handle other kinds of writes from the 387 */
  1548.  
  1549.   if (STACK_TOP_P (operands[1]))
  1550.     {
  1551.       output_asm_insn (AS1 (fstp%z0,%y0), operands);
  1552.       if (! stack_top_dies)
  1553.     return AS1 (fld%z0,%y0);
  1554.  
  1555.       RET;
  1556.     }
  1557.  
  1558.   /* Handle other kinds of reads to the 387 */
  1559.  
  1560.   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  1561.     return output_move_const_single (operands);
  1562.  
  1563.   if (STACK_TOP_P (operands[0]))
  1564.        return AS1 (fld%z1,%y1);
  1565.  
  1566.   /* Handle all XFmode moves not involving the 387 */
  1567.  
  1568.   return output_move_double (operands);
  1569. }")
  1570.  
  1571. (define_insn "swapxf"
  1572.   [(set (match_operand:XF 0 "register_operand" "f")
  1573.     (match_operand:XF 1 "register_operand" "f"))
  1574.    (set (match_dup 1)
  1575.     (match_dup 0))]
  1576.   ""
  1577.   "*
  1578. {
  1579.   if (STACK_TOP_P (operands[0]))
  1580.     return AS1 (fxch,%1);
  1581.   else
  1582.     return AS1 (fxch,%0);
  1583. }")
  1584.  
  1585. (define_insn ""
  1586.   [(set (match_operand:DI 0 "push_operand" "=<,<,<,<")
  1587.     (match_operand:DI 1 "general_operand" "riF,o,o,o"))
  1588.    (clobber (match_scratch:SI 2 "=X,&r,&r,X"))
  1589.    (clobber (match_scratch:SI 3 "=X,&r,X,X"))]
  1590.   ""
  1591.   "*
  1592. {
  1593.   if (GET_CODE (operands[1]) != MEM)
  1594.     return output_move_double (operands);
  1595.  
  1596.   else
  1597.     return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
  1598. }")
  1599.  
  1600. (define_insn "movdi"
  1601.   [(set (match_operand:DI 0 "general_operand" "=o,o,r,rm")
  1602.     (match_operand:DI 1 "general_operand" "o,o,m,riF"))
  1603.    (clobber (match_scratch:SI 2 "=&r,&r,X,X"))
  1604.    (clobber (match_scratch:SI 3 "=&r,X,X,X"))]
  1605.   ""
  1606.   "*
  1607. {
  1608.   rtx low[2], high[2], xop[6];
  1609.  
  1610.   if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
  1611.     return output_move_double (operands);
  1612.   else
  1613.     return output_move_memory (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
  1614. }")
  1615.  
  1616.  
  1617. ;;- conversion instructions
  1618. ;;- NONE
  1619.  
  1620. ;;- zero extension instructions
  1621. ;; See comments by `andsi' for when andl is faster than movzx.
  1622.  
  1623. (define_insn "zero_extendhisi2"
  1624.   [(set (match_operand:SI 0 "general_operand" "=r")
  1625.     (zero_extend:SI
  1626.      (match_operand:HI 1 "nonimmediate_operand" "rm")))]
  1627.   ""
  1628.   "*
  1629. {
  1630.   if ((!TARGET_386 || REGNO (operands[0]) == 0)
  1631.       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  1632.     {
  1633.       rtx xops[2];
  1634.       xops[0] = operands[0];
  1635.       xops[1] = GEN_INT (0xffff);
  1636.       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  1637.       RET;
  1638.     }
  1639.  
  1640. #ifdef INTEL_SYNTAX
  1641.   return AS2 (movzx,%1,%0);
  1642. #else
  1643.   return AS2 (movz%W0%L0,%1,%0);
  1644. #endif
  1645. }")
  1646.  
  1647. (define_insn "zero_extendqihi2"
  1648.   [(set (match_operand:HI 0 "general_operand" "=r")
  1649.     (zero_extend:HI
  1650.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1651.   ""
  1652.   "*
  1653. {
  1654.   if ((!TARGET_386 || REGNO (operands[0]) == 0)
  1655.       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  1656.     {
  1657.       rtx xops[2];
  1658.       xops[0] = operands[0];
  1659.       xops[1] = GEN_INT (0xff);
  1660.       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  1661.       RET;
  1662.     }
  1663.  
  1664. #ifdef INTEL_SYNTAX
  1665.   return AS2 (movzx,%1,%0);
  1666. #else
  1667.   return AS2 (movz%B0%W0,%1,%0);
  1668. #endif
  1669. }")
  1670.  
  1671. (define_insn "zero_extendqisi2"
  1672.   [(set (match_operand:SI 0 "general_operand" "=r")
  1673.     (zero_extend:SI
  1674.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1675.   ""
  1676.   "*
  1677. {
  1678.   if ((!TARGET_386 || REGNO (operands[0]) == 0)
  1679.       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  1680.     {
  1681.       rtx xops[2];
  1682.       xops[0] = operands[0];
  1683.       xops[1] = GEN_INT (0xff);
  1684.       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  1685.       RET;
  1686.     }
  1687.  
  1688. #ifdef INTEL_SYNTAX
  1689.   return AS2 (movzx,%1,%0);
  1690. #else
  1691.   return AS2 (movz%B0%L0,%1,%0);
  1692. #endif
  1693. }")
  1694.  
  1695. (define_insn "zero_extendsidi2"
  1696.   [(set (match_operand:DI 0 "register_operand" "=r")
  1697.     (zero_extend:DI
  1698.      (match_operand:SI 1 "register_operand" "0")))]
  1699.   ""
  1700.   "*
  1701. {
  1702.   operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1703.   return AS2 (xor%L0,%0,%0);
  1704. }")
  1705.  
  1706. ;;- sign extension instructions
  1707.  
  1708. (define_insn "extendsidi2"
  1709.   [(set (match_operand:DI 0 "register_operand" "=r")
  1710.     (sign_extend:DI
  1711.      (match_operand:SI 1 "register_operand" "0")))]
  1712.   ""
  1713.   "*
  1714. {
  1715.   if (REGNO (operands[0]) == 0)
  1716.     {
  1717.       /* This used to be cwtl, but that extends HI to SI somehow.  */
  1718. #ifdef INTEL_SYNTAX
  1719.       return \"cdq\";
  1720. #else
  1721.       return \"cltd\";
  1722. #endif
  1723.     }
  1724.  
  1725.   operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1726.   output_asm_insn (AS2 (mov%L0,%0,%1), operands);
  1727.  
  1728.   operands[0] = GEN_INT (31);
  1729.   return AS2 (sar%L1,%0,%1);
  1730. }")
  1731.  
  1732. ;; Note that the i386 programmers' manual says that the opcodes
  1733. ;; are named movsx..., but the assembler on Unix does not accept that.
  1734. ;; We use what the Unix assembler expects.
  1735.  
  1736. (define_insn "extendhisi2"
  1737.   [(set (match_operand:SI 0 "general_operand" "=r")
  1738.     (sign_extend:SI
  1739.      (match_operand:HI 1 "nonimmediate_operand" "rm")))]
  1740.   ""
  1741.   "*
  1742. {
  1743.   if (REGNO (operands[0]) == 0
  1744.       && REG_P (operands[1]) && REGNO (operands[1]) == 0)
  1745. #ifdef INTEL_SYNTAX
  1746.     return \"cwde\";
  1747. #else
  1748.     return \"cwtl\";
  1749. #endif
  1750.  
  1751. #ifdef INTEL_SYNTAX
  1752.   return AS2 (movsx,%1,%0);
  1753. #else
  1754.   return AS2 (movs%W0%L0,%1,%0);
  1755. #endif
  1756. }")
  1757.  
  1758. (define_insn "extendqihi2"
  1759.   [(set (match_operand:HI 0 "general_operand" "=r")
  1760.     (sign_extend:HI
  1761.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1762.   ""
  1763.   "*
  1764. {
  1765.   if (REGNO (operands[0]) == 0
  1766.       && REG_P (operands[1]) && REGNO (operands[1]) == 0)
  1767.     return \"cbtw\";
  1768.  
  1769. #ifdef INTEL_SYNTAX
  1770.   return AS2 (movsx,%1,%0);
  1771. #else
  1772.   return AS2 (movs%B0%W0,%1,%0);
  1773. #endif
  1774. }")
  1775.  
  1776. (define_insn "extendqisi2"
  1777.   [(set (match_operand:SI 0 "general_operand" "=r")
  1778.     (sign_extend:SI
  1779.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1780.   ""
  1781.   "*
  1782. {
  1783. #ifdef INTEL_SYNTAX
  1784.   return AS2 (movsx,%1,%0);
  1785. #else
  1786.   return AS2 (movs%B0%L0,%1,%0);
  1787. #endif
  1788. }")
  1789.  
  1790. ;; Conversions between float and double.
  1791.  
  1792. (define_insn "extendsfdf2"
  1793.   [(set (match_operand:DF 0 "general_operand" "=fm,f")
  1794.     (float_extend:DF
  1795.      (match_operand:SF 1 "general_operand" "f,fm")))]
  1796.   "TARGET_80387"
  1797.   "*
  1798. {
  1799.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1800.  
  1801.   if (NON_STACK_REG_P (operands[1]))
  1802.     {
  1803.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1804.       RET;
  1805.     }
  1806.  
  1807.   if (NON_STACK_REG_P (operands[0]))
  1808.     {
  1809.       output_to_reg (operands[0], stack_top_dies);
  1810.       RET;
  1811.     }
  1812.  
  1813.   if (STACK_TOP_P (operands[0]))
  1814.     return AS1 (fld%z1,%y1);
  1815.  
  1816.   if (GET_CODE (operands[0]) == MEM)
  1817.     {
  1818.       if (stack_top_dies)
  1819.     return AS1 (fstp%z0,%y0);
  1820.       else
  1821.         return AS1 (fst%z0,%y0);
  1822.     }
  1823.  
  1824.   abort ();
  1825. }")
  1826.  
  1827. (define_insn "extenddfxf2"
  1828.   [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r")
  1829.     (float_extend:XF
  1830.      (match_operand:DF 1 "general_operand" "f,fm,!*r,f")))]
  1831.   "TARGET_80387"
  1832.   "*
  1833. {
  1834.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1835.  
  1836.   if (NON_STACK_REG_P (operands[1]))
  1837.     {
  1838.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1839.       RET;
  1840.     }
  1841.  
  1842.   if (NON_STACK_REG_P (operands[0]))
  1843.     {
  1844.       output_to_reg (operands[0], stack_top_dies);
  1845.       RET;
  1846.     }
  1847.  
  1848.   if (STACK_TOP_P (operands[0]))
  1849.     return AS1 (fld%z1,%y1);
  1850.  
  1851.   if (GET_CODE (operands[0]) == MEM)
  1852.     {
  1853.       output_asm_insn (AS1 (fstp%z0,%y0), operands);
  1854.       if (! stack_top_dies)
  1855.     return AS1 (fld%z0,%y0);
  1856.       RET;
  1857.     }
  1858.  
  1859.   abort ();
  1860. }")
  1861.  
  1862. (define_insn "extendsfxf2"
  1863.   [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r")
  1864.     (float_extend:XF
  1865.      (match_operand:SF 1 "general_operand" "f,fm,!*r,f")))]
  1866.   "TARGET_80387"
  1867.   "*
  1868. {
  1869.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1870.  
  1871.   if (NON_STACK_REG_P (operands[1]))
  1872.     {
  1873.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1874.       RET;
  1875.     }
  1876.  
  1877.   if (NON_STACK_REG_P (operands[0]))
  1878.     {
  1879.       output_to_reg (operands[0], stack_top_dies);
  1880.       RET;
  1881.     }
  1882.  
  1883.   if (STACK_TOP_P (operands[0]))
  1884.     return AS1 (fld%z1,%y1);
  1885.  
  1886.   if (GET_CODE (operands[0]) == MEM)
  1887.     {
  1888.       output_asm_insn (AS1 (fstp%z0,%y0), operands);
  1889.       if (! stack_top_dies)
  1890.     return AS1 (fld%z0,%y0);
  1891.       RET;
  1892.     }
  1893.  
  1894.   abort ();
  1895. }")
  1896.  
  1897. (define_expand "truncdfsf2"
  1898.   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
  1899.            (float_truncate:SF
  1900.             (match_operand:DF 1 "register_operand" "")))
  1901.           (clobber (match_dup 2))])]
  1902.   "TARGET_80387"
  1903.   "
  1904. {
  1905.   operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
  1906. }")
  1907.  
  1908. ;; This cannot output into an f-reg because there is no way to be sure
  1909. ;; of truncating in that case.  Otherwise this is just like a simple move
  1910. ;; insn.  So we pretend we can output to a reg in order to get better
  1911. ;; register preferencing, but we really use a stack slot.
  1912.  
  1913. (define_insn ""
  1914.   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
  1915.     (float_truncate:SF
  1916.      (match_operand:DF 1 "register_operand" "0,f")))
  1917.    (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
  1918.   "TARGET_80387"
  1919.   "*
  1920. {
  1921.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1922.  
  1923.   if (GET_CODE (operands[0]) == MEM)
  1924.     {
  1925.       if (stack_top_dies)
  1926.     return AS1 (fstp%z0,%0);
  1927.       else
  1928.         return AS1 (fst%z0,%0);
  1929.     }
  1930.   else if (STACK_TOP_P (operands[0]))
  1931.     {
  1932.       output_asm_insn (AS1 (fstp%z2,%y2), operands);
  1933.       return AS1 (fld%z2,%y2);
  1934.     }
  1935.   else
  1936.     abort ();
  1937. }")
  1938.  
  1939. (define_insn "truncxfsf2"
  1940.   [(set (match_operand:SF 0 "general_operand" "=m,!*r")
  1941.     (float_truncate:SF
  1942.      (match_operand:XF 1 "register_operand" "f,f")))]
  1943.   "TARGET_80387"
  1944.   "*
  1945. {
  1946.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1947.  
  1948.   if (NON_STACK_REG_P (operands[0]))
  1949.     {
  1950.       if (stack_top_dies == 0)
  1951.     {
  1952.       output_asm_insn (AS1 (fld,%y1), operands);
  1953.       stack_top_dies = 1;
  1954.     }
  1955.       output_to_reg (operands[0], stack_top_dies);
  1956.       RET;
  1957.     }
  1958.   else if (GET_CODE (operands[0]) == MEM)
  1959.     {
  1960.       if (stack_top_dies)
  1961.     return AS1 (fstp%z0,%0);
  1962.       else
  1963.     {
  1964.       output_asm_insn (AS1 (fld,%y1), operands);
  1965.       return AS1 (fstp%z0,%0);
  1966.     }
  1967.     }
  1968.   else
  1969.     abort ();
  1970. }")
  1971.  
  1972. (define_insn "truncxfdf2"
  1973.   [(set (match_operand:DF 0 "general_operand" "=m,!*r")
  1974.     (float_truncate:DF
  1975.      (match_operand:XF 1 "register_operand" "f,f")))]
  1976.   "TARGET_80387"
  1977.   "*
  1978. {
  1979.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1980.  
  1981.   if (NON_STACK_REG_P (operands[0]))
  1982.     {
  1983.       if (stack_top_dies == 0)
  1984.     {
  1985.       output_asm_insn (AS1 (fld,%y1), operands);
  1986.       stack_top_dies = 1;
  1987.     }
  1988.       output_to_reg (operands[0], stack_top_dies);
  1989.       RET;
  1990.     }
  1991.   else if (GET_CODE (operands[0]) == MEM)
  1992.     {
  1993.       if (stack_top_dies)
  1994.     return AS1 (fstp%z0,%0);
  1995.       else
  1996.     {
  1997.       output_asm_insn (AS1 (fld,%y1), operands);
  1998.       return AS1 (fstp%z0,%0);
  1999.     }
  2000.     }
  2001.   else
  2002.     abort ();
  2003. }")
  2004.  
  2005.  
  2006. ;; The 387 requires that the stack top dies after converting to DImode.
  2007.  
  2008. ;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
  2009. ;; doing a signed conversion to DImode, and then taking just the low
  2010. ;; part.
  2011.  
  2012. (define_expand "fixuns_truncxfsi2"
  2013.   [(set (match_dup 4)
  2014.     (match_operand:XF 1 "register_operand" ""))
  2015.    (parallel [(set (match_dup 2)
  2016.            (fix:DI (fix:XF (match_dup 4))))
  2017.           (clobber (match_dup 4))
  2018.           (clobber (match_dup 5))
  2019.           (clobber (match_dup 6))
  2020.           (clobber (match_scratch:SI 7 ""))])
  2021.    (set (match_operand:SI 0 "general_operand" "")
  2022.     (match_dup 3))]
  2023.   "TARGET_80387"
  2024.   "
  2025. {
  2026.   operands[2] = gen_reg_rtx (DImode);
  2027.   operands[3] = gen_lowpart (SImode, operands[2]);
  2028.   operands[4] = gen_reg_rtx (XFmode);
  2029.   operands[5] = (rtx) assign_386_stack_local (SImode, 0);
  2030.   operands[6] = (rtx) assign_386_stack_local (SImode, 1);
  2031. }")
  2032.  
  2033. (define_expand "fixuns_truncdfsi2"
  2034.   [(set (match_dup 4)
  2035.     (match_operand:DF 1 "register_operand" ""))
  2036.    (parallel [(set (match_dup 2)
  2037.            (fix:DI (fix:DF (match_dup 4))))
  2038.           (clobber (match_dup 4))
  2039.           (clobber (match_dup 5))
  2040.           (clobber (match_dup 6))
  2041.           (clobber (match_scratch:SI 7 ""))])
  2042.    (set (match_operand:SI 0 "general_operand" "")
  2043.     (match_dup 3))]
  2044.   "TARGET_80387"
  2045.   "
  2046. {
  2047.   operands[2] = gen_reg_rtx (DImode);
  2048.   operands[3] = gen_lowpart (SImode, operands[2]);
  2049.   operands[4] = gen_reg_rtx (DFmode);
  2050.   operands[5] = (rtx) assign_386_stack_local (SImode, 0);
  2051.   operands[6] = (rtx) assign_386_stack_local (SImode, 1);
  2052. }")
  2053.  
  2054. (define_expand "fixuns_truncsfsi2"
  2055.   [(set (match_dup 4)
  2056.     (match_operand:SF 1 "register_operand" ""))
  2057.    (parallel [(set (match_dup 2)
  2058.            (fix:DI (fix:SF (match_dup 4))))
  2059.           (clobber (match_dup 4))
  2060.           (clobber (match_dup 5))
  2061.           (clobber (match_dup 6))
  2062.           (clobber (match_scratch:SI 7 ""))])
  2063.    (set (match_operand:SI 0 "general_operand" "")
  2064.     (match_dup 3))]
  2065.   "TARGET_80387"
  2066.   "
  2067. {
  2068.   operands[2] = gen_reg_rtx (DImode);
  2069.   operands[3] = gen_lowpart (SImode, operands[2]);
  2070.   operands[4] = gen_reg_rtx (SFmode);
  2071.   operands[5] = (rtx) assign_386_stack_local (SImode, 0);
  2072.   operands[6] = (rtx) assign_386_stack_local (SImode, 1);
  2073. }")
  2074.  
  2075. ;; Signed conversion to DImode.
  2076.  
  2077. (define_expand "fix_truncxfdi2"
  2078.   [(set (match_dup 2)
  2079.     (match_operand:XF 1 "register_operand" ""))
  2080.    (parallel [(set (match_operand:DI 0 "general_operand" "")
  2081.            (fix:DI (fix:XF (match_dup 2))))
  2082.           (clobber (match_dup 2))
  2083.           (clobber (match_dup 3))
  2084.           (clobber (match_dup 4))
  2085.           (clobber (match_scratch:SI 5 ""))])]
  2086.   "TARGET_80387"
  2087.   "
  2088. {
  2089.   operands[1] = copy_to_mode_reg (XFmode, operands[1]);
  2090.   operands[2] = gen_reg_rtx (XFmode);
  2091.   operands[3] = (rtx) assign_386_stack_local (SImode, 0);
  2092.   operands[4] = (rtx) assign_386_stack_local (SImode, 1);
  2093. }")
  2094.  
  2095. (define_expand "fix_truncdfdi2"
  2096.   [(set (match_dup 2)
  2097.     (match_operand:DF 1 "register_operand" ""))
  2098.    (parallel [(set (match_operand:DI 0 "general_operand" "")
  2099.            (fix:DI (fix:DF (match_dup 2))))
  2100.           (clobber (match_dup 2))
  2101.           (clobber (match_dup 3))
  2102.           (clobber (match_dup 4))
  2103.           (clobber (match_scratch:SI 5 ""))])]
  2104.   "TARGET_80387"
  2105.   "
  2106. {
  2107.   operands[1] = copy_to_mode_reg (DFmode, operands[1]);
  2108.   operands[2] = gen_reg_rtx (DFmode);
  2109.   operands[3] = (rtx) assign_386_stack_local (SImode, 0);
  2110.   operands[4] = (rtx) assign_386_stack_local (SImode, 1);
  2111. }")
  2112.  
  2113. (define_expand "fix_truncsfdi2"
  2114.   [(set (match_dup 2)
  2115.     (match_operand:SF 1 "register_operand" ""))
  2116.    (parallel [(set (match_operand:DI 0 "general_operand" "")
  2117.            (fix:DI (fix:SF (match_dup 2))))
  2118.           (clobber (match_dup 2))
  2119.           (clobber (match_dup 3))
  2120.           (clobber (match_dup 4))
  2121.           (clobber (match_scratch:SI 5 ""))])]
  2122.   "TARGET_80387"
  2123.   "
  2124. {
  2125.   operands[1] = copy_to_mode_reg (SFmode, operands[1]);
  2126.   operands[2] = gen_reg_rtx (SFmode);
  2127.   operands[3] = (rtx) assign_386_stack_local (SImode, 0);
  2128.   operands[4] = (rtx) assign_386_stack_local (SImode, 1);
  2129. }")
  2130.  
  2131. ;; These match a signed conversion of either DFmode or SFmode to DImode.
  2132.  
  2133. (define_insn ""
  2134.   [(set (match_operand:DI 0 "general_operand" "=rm")
  2135.     (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
  2136.    (clobber (match_dup 1))
  2137.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  2138.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  2139.    (clobber (match_scratch:SI 4 "=&q"))]
  2140.   "TARGET_80387"
  2141.   "* return output_fix_trunc (insn, operands);")
  2142.  
  2143. (define_insn ""
  2144.   [(set (match_operand:DI 0 "general_operand" "=rm")
  2145.     (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
  2146.    (clobber (match_dup 1))
  2147.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  2148.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  2149.    (clobber (match_scratch:SI 4 "=&q"))]
  2150.   "TARGET_80387"
  2151.   "* return output_fix_trunc (insn, operands);")
  2152.  
  2153. (define_insn ""
  2154.   [(set (match_operand:DI 0 "general_operand" "=rm")
  2155.     (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
  2156.    (clobber (match_dup 1))
  2157.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  2158.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  2159.    (clobber (match_scratch:SI 4 "=&q"))]
  2160.   "TARGET_80387"
  2161.   "* return output_fix_trunc (insn, operands);")
  2162.  
  2163. ;; Signed MODE_FLOAT conversion to SImode.
  2164.  
  2165. (define_expand "fix_truncxfsi2"
  2166.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  2167.            (fix:SI
  2168.             (fix:XF (match_operand:XF 1 "register_operand" ""))))
  2169.           (clobber (match_dup 2))
  2170.           (clobber (match_dup 3))
  2171.           (clobber (match_scratch:SI 4 ""))])]
  2172.   "TARGET_80387"
  2173.   "
  2174. {
  2175.   operands[2] = (rtx) assign_386_stack_local (SImode, 0);
  2176.   operands[3] = (rtx) assign_386_stack_local (SImode, 1);
  2177. }")
  2178.  
  2179. (define_expand "fix_truncdfsi2"
  2180.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  2181.            (fix:SI
  2182.             (fix:DF (match_operand:DF 1 "register_operand" ""))))
  2183.           (clobber (match_dup 2))
  2184.           (clobber (match_dup 3))
  2185.           (clobber (match_scratch:SI 4 ""))])]
  2186.   "TARGET_80387"
  2187.   "
  2188. {
  2189.   operands[2] = (rtx) assign_386_stack_local (SImode, 0);
  2190.   operands[3] = (rtx) assign_386_stack_local (SImode, 1);
  2191. }")
  2192.  
  2193. (define_expand "fix_truncsfsi2"
  2194.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  2195.            (fix:SI
  2196.             (fix:SF (match_operand:SF 1 "register_operand" ""))))
  2197.           (clobber (match_dup 2))
  2198.           (clobber (match_dup 3))
  2199.           (clobber (match_scratch:SI 4 ""))])]
  2200.   "TARGET_80387"
  2201.   "
  2202. {
  2203.   operands[2] = (rtx) assign_386_stack_local (SImode, 0);
  2204.   operands[3] = (rtx) assign_386_stack_local (SImode, 1);
  2205. }")
  2206.  
  2207. (define_insn ""
  2208.   [(set (match_operand:SI 0 "general_operand" "=rm")
  2209.     (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
  2210.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  2211.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  2212.    (clobber (match_scratch:SI 4 "=&q"))]
  2213.   "TARGET_80387"
  2214.   "* return output_fix_trunc (insn, operands);")
  2215.  
  2216. (define_insn ""
  2217.   [(set (match_operand:SI 0 "general_operand" "=rm")
  2218.     (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
  2219.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  2220.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  2221.    (clobber (match_scratch:SI 4 "=&q"))]
  2222.   "TARGET_80387"
  2223.   "* return output_fix_trunc (insn, operands);")
  2224.  
  2225. (define_insn ""
  2226.   [(set (match_operand:SI 0 "general_operand" "=rm")
  2227.     (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
  2228.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  2229.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  2230.    (clobber (match_scratch:SI 4 "=&q"))]
  2231.   "TARGET_80387"
  2232.   "* return output_fix_trunc (insn, operands);")
  2233.  
  2234. ;; Conversion between fixed point and floating point.
  2235. ;; The actual pattern that matches these is at the end of this file.
  2236.  
  2237. ;; ??? Possibly represent floatunssidf2 here in gcc2.
  2238.  
  2239. (define_expand "floatsisf2"
  2240.   [(set (match_operand:SF 0 "register_operand" "")
  2241.     (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
  2242.   "TARGET_80387"
  2243.   "")
  2244.  
  2245. (define_expand "floatdisf2"
  2246.   [(set (match_operand:SF 0 "register_operand" "")
  2247.     (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
  2248.   "TARGET_80387"
  2249.   "")
  2250.  
  2251. (define_expand "floatsidf2"
  2252.   [(set (match_operand:DF 0 "register_operand" "")
  2253.     (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
  2254.   "TARGET_80387"
  2255.   "")
  2256.  
  2257. (define_expand "floatdidf2"
  2258.   [(set (match_operand:DF 0 "register_operand" "")
  2259.     (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
  2260.   "TARGET_80387"
  2261.   "")
  2262.  
  2263. (define_expand "floatsixf2"
  2264.   [(set (match_operand:XF 0 "register_operand" "")
  2265.     (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
  2266.   "TARGET_80387"
  2267.   "")
  2268.  
  2269. (define_expand "floatdixf2"
  2270.   [(set (match_operand:XF 0 "register_operand" "")
  2271.     (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
  2272.   "TARGET_80387"
  2273.   "")
  2274.  
  2275. ;; This will convert from SImode or DImode to MODE_FLOAT.
  2276.  
  2277. (define_insn ""
  2278.   [(set (match_operand:XF 0 "register_operand" "=f")
  2279.     (float:XF (match_operand:DI 1 "general_operand" "rm")))]
  2280.   "TARGET_80387"
  2281.   "*
  2282. {
  2283.   if (NON_STACK_REG_P (operands[1]))
  2284.     {
  2285.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2286.       RET;
  2287.     }
  2288.   else if (GET_CODE (operands[1]) == MEM)
  2289.     return AS1 (fild%z1,%1);
  2290.   else
  2291.     abort ();
  2292. }")
  2293.  
  2294. (define_insn ""
  2295.   [(set (match_operand:DF 0 "register_operand" "=f")
  2296.     (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
  2297.   "TARGET_80387"
  2298.   "*
  2299. {
  2300.   if (NON_STACK_REG_P (operands[1]))
  2301.     {
  2302.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2303.       RET;
  2304.     }
  2305.   else if (GET_CODE (operands[1]) == MEM)
  2306.     return AS1 (fild%z1,%1);
  2307.   else
  2308.     abort ();
  2309. }")
  2310.  
  2311. (define_insn ""
  2312.   [(set (match_operand:SF 0 "register_operand" "=f")
  2313.     (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
  2314.   "TARGET_80387"
  2315.   "*
  2316. {
  2317.   if (NON_STACK_REG_P (operands[1]))
  2318.     {
  2319.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2320.       RET;
  2321.     }
  2322.   else if (GET_CODE (operands[1]) == MEM)
  2323.     return AS1 (fild%z1,%1);
  2324.   else
  2325.     abort ();
  2326. }")
  2327.  
  2328. (define_insn ""
  2329.   [(set (match_operand:DF 0 "register_operand" "=f")
  2330.     (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  2331.   "TARGET_80387"
  2332.   "*
  2333. {
  2334.   if (NON_STACK_REG_P (operands[1]))
  2335.     {
  2336.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2337.       RET;
  2338.     }
  2339.   else if (GET_CODE (operands[1]) == MEM)
  2340.     return AS1 (fild%z1,%1);
  2341.   else
  2342.     abort ();
  2343. }")
  2344.  
  2345. (define_insn ""
  2346.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  2347.     (float:XF (match_operand:SI 1 "general_operand" "m,!*r")))]
  2348.   "TARGET_80387"
  2349.   "*
  2350. {
  2351.   if (NON_STACK_REG_P (operands[1]))
  2352.     {
  2353.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2354.       RET;
  2355.     }
  2356.   else if (GET_CODE (operands[1]) == MEM)
  2357.     return AS1 (fild%z1,%1);
  2358.   else
  2359.     abort ();
  2360. }")
  2361.  
  2362. (define_insn ""
  2363.   [(set (match_operand:SF 0 "register_operand" "=f")
  2364.     (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  2365.   "TARGET_80387"
  2366.   "*
  2367. {
  2368.   if (NON_STACK_REG_P (operands[1]))
  2369.     {
  2370.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2371.       RET;
  2372.     }
  2373.   else if (GET_CODE (operands[1]) == MEM)
  2374.     return AS1 (fild%z1,%1);
  2375.   else
  2376.     abort ();
  2377. }")
  2378.  
  2379. ;;- add instructions
  2380.  
  2381. (define_insn "adddi3"
  2382.   [(set (match_operand:DI 0 "general_operand" "=&r,ro,o,&r,ro,o,&r,o,o,o")
  2383.     (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,o,riF,o,or,riF,riF,o")
  2384.          (match_operand:DI 2 "general_operand" "o,riF,o,0,0,0,oriF,riF,o,o")))
  2385.    (clobber (match_scratch:SI 3 "=X,X,&r,X,X,&r,X,X,&r,&r"))]
  2386.   ""
  2387.   "*
  2388. {
  2389.   rtx low[3], high[3], xops[7], temp;
  2390.  
  2391.   CC_STATUS_INIT;
  2392.  
  2393.   if (rtx_equal_p (operands[0], operands[2]))
  2394.     {
  2395.       temp = operands[1];
  2396.       operands[1] = operands[2];
  2397.       operands[2] = temp;
  2398.     }
  2399.  
  2400.   split_di (operands, 3, low, high);
  2401.   if (!rtx_equal_p (operands[0], operands[1]))
  2402.     {
  2403.       xops[0] = high[0];
  2404.       xops[1] = low[0];
  2405.       xops[2] = high[1];
  2406.       xops[3] = low[1];
  2407.  
  2408.       if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
  2409.     {
  2410.       output_asm_insn (AS2 (mov%L1,%3,%1), xops);
  2411.       output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  2412.     }
  2413.       else
  2414.     {
  2415.       xops[4] = high[2];
  2416.       xops[5] = low[2];
  2417.       xops[6] = operands[3];
  2418.       output_asm_insn (AS2 (mov%L6,%3,%6), xops);
  2419.       output_asm_insn (AS2 (add%L6,%5,%6), xops);
  2420.       output_asm_insn (AS2 (mov%L1,%6,%1), xops);
  2421.       output_asm_insn (AS2 (mov%L6,%2,%6), xops);
  2422.       output_asm_insn (AS2 (adc%L6,%4,%6), xops);
  2423.       output_asm_insn (AS2 (mov%L0,%6,%0), xops);
  2424.       RET;
  2425.     }
  2426.     }
  2427.  
  2428.   if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
  2429.     {
  2430.       xops[0] = high[0];
  2431.       xops[1] = low[0];
  2432.       xops[2] = high[2];
  2433.       xops[3] = low[2];
  2434.       xops[4] = operands[3];
  2435.  
  2436.       output_asm_insn (AS2 (mov%L4,%3,%4), xops);
  2437.       output_asm_insn (AS2 (add%L1,%4,%1), xops);
  2438.       output_asm_insn (AS2 (mov%L4,%2,%4), xops);
  2439.       output_asm_insn (AS2 (adc%L0,%4,%0), xops);
  2440.     }
  2441.  
  2442.   else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
  2443.     {
  2444.       output_asm_insn (AS2 (add%L0,%2,%0), low);
  2445.       output_asm_insn (AS2 (adc%L0,%2,%0), high);
  2446.     }
  2447.  
  2448.   else
  2449.     output_asm_insn (AS2 (add%L0,%2,%0), high);
  2450.  
  2451.   RET;
  2452. }")
  2453.  
  2454. ;; On a 486, it is faster to do movl/addl than to do a single leal if
  2455. ;; operands[1] and operands[2] are both registers.
  2456.  
  2457. (define_insn "addsi3"
  2458.   [(set (match_operand:SI 0 "general_operand" "=?r,rm,r")
  2459.     (plus:SI (match_operand:SI 1 "general_operand" "%r,0,0")
  2460.          (match_operand:SI 2 "general_operand" "ri,ri,rm")))]
  2461.   ""
  2462.   "*
  2463. {
  2464.   if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
  2465.     {
  2466.       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
  2467.     return AS2 (add%L0,%1,%0);
  2468.  
  2469.       if (operands[2] == stack_pointer_rtx)
  2470.     {
  2471.       rtx temp;
  2472.  
  2473.       temp = operands[1];
  2474.       operands[1] = operands[2];
  2475.       operands[2] = temp;
  2476.     }
  2477.  
  2478.       if (operands[2] != stack_pointer_rtx)
  2479.     {
  2480.       CC_STATUS_INIT;
  2481.       operands[1] = SET_SRC (PATTERN (insn));
  2482.       return AS2 (lea%L0,%a1,%0);
  2483.     }
  2484.  
  2485.       output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  2486.     }
  2487.  
  2488.   if (operands[2] == const1_rtx)
  2489.     return AS1 (inc%L0,%0);
  2490.  
  2491.   if (operands[2] == constm1_rtx)
  2492.     return AS1 (dec%L0,%0);
  2493.  
  2494.   return AS2 (add%L0,%2,%0);
  2495. }")
  2496.  
  2497. ;; ??? `lea' here, for three operand add?  If leaw is used, only %bx,
  2498. ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
  2499. ;; able to handle the operand.  But leal always works?
  2500.  
  2501. (define_insn "addhi3"
  2502.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2503.     (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
  2504.          (match_operand:HI 2 "general_operand" "ri,rm")))]
  2505.   ""
  2506.   "*
  2507. {
  2508.   /* ??? what about offsettable memory references? */
  2509.   if (QI_REG_P (operands[0])
  2510.       && GET_CODE (operands[2]) == CONST_INT
  2511.       && (INTVAL (operands[2]) & 0xff) == 0)
  2512.     {
  2513.       int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
  2514.       CC_STATUS_INIT;
  2515.  
  2516.       if (byteval == 1)
  2517.     return AS1 (inc%B0,%h0);
  2518.       else if (byteval == 255)
  2519.     return AS1 (dec%B0,%h0);
  2520.  
  2521.       operands[2] = GEN_INT (byteval);
  2522.       return AS2 (add%B0,%2,%h0);
  2523.     }
  2524.  
  2525.   if (operands[2] == const1_rtx)
  2526.     return AS1 (inc%W0,%0);
  2527.  
  2528.   if (operands[2] == constm1_rtx
  2529.       || (GET_CODE (operands[2]) == CONST_INT
  2530.       && INTVAL (operands[2]) == 65535))
  2531.     return AS1 (dec%W0,%0);
  2532.  
  2533.   return AS2 (add%W0,%2,%0);
  2534. }")
  2535.  
  2536. (define_insn "addqi3"
  2537.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2538.     (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
  2539.          (match_operand:QI 2 "general_operand" "qn,qmn")))]
  2540.   ""
  2541.   "*
  2542. {
  2543.   if (operands[2] == const1_rtx)
  2544.     return AS1 (inc%B0,%0);
  2545.  
  2546.   if (operands[2] == constm1_rtx
  2547.       || (GET_CODE (operands[2]) == CONST_INT
  2548.       && INTVAL (operands[2]) == 255))
  2549.     return AS1 (dec%B0,%0);
  2550.  
  2551.   return AS2 (add%B0,%2,%0);
  2552. }")
  2553.  
  2554. ;Lennart Augustsson <augustss@cs.chalmers.se>
  2555. ;says this pattern just makes slower code:
  2556. ;    pushl    %ebp
  2557. ;    addl    $-80,(%esp)
  2558. ;instead of
  2559. ;    leal    -80(%ebp),%eax
  2560. ;    pushl    %eax
  2561. ;
  2562. ;(define_insn ""
  2563. ;  [(set (match_operand:SI 0 "push_operand" "=<")
  2564. ;    (plus:SI (match_operand:SI 1 "general_operand" "%r")
  2565. ;         (match_operand:SI 2 "general_operand" "ri")))]
  2566. ;  ""
  2567. ;  "*
  2568. ;{
  2569. ;  rtx xops[4];
  2570. ;  xops[0] = operands[0];
  2571. ;  xops[1] = operands[1];
  2572. ;  xops[2] = operands[2];
  2573. ;  xops[3] = gen_rtx (MEM, SImode, stack_pointer_rtx);
  2574. ;  output_asm_insn (\"push%z1 %1\", xops);
  2575. ;  output_asm_insn (AS2 (add%z3,%2,%3), xops);
  2576. ;  RET;
  2577. ;}")
  2578.  
  2579. ;; addsi3 is faster, so put this after.
  2580.  
  2581. (define_insn "movsi_lea"
  2582.   [(set (match_operand:SI 0 "register_operand" "=r")
  2583.         (match_operand:QI 1 "address_operand" "p"))]
  2584.   ""
  2585.   "*
  2586. {
  2587.   CC_STATUS_INIT;
  2588.   /* Adding a constant to a register is faster with an add.  */
  2589.   /* ??? can this ever happen? */
  2590.   if (GET_CODE (operands[1]) == PLUS
  2591.       && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
  2592.       && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
  2593.     {
  2594.       operands[1] = XEXP (operands[1], 1);
  2595.  
  2596.       if (operands[1] == const1_rtx)
  2597.         return AS1 (inc%L0,%0);
  2598.  
  2599.       if (operands[1] == constm1_rtx)
  2600.         return AS1 (dec%L0,%0);
  2601.  
  2602.       return AS2 (add%L0,%1,%0);
  2603.     }
  2604.   return AS2 (lea%L0,%a1,%0);
  2605. }")
  2606.  
  2607. ;; The patterns that match these are at the end of this file.
  2608.  
  2609. (define_expand "addxf3"
  2610.   [(set (match_operand:XF 0 "register_operand" "")
  2611.     (plus:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2612.          (match_operand:XF 2 "nonimmediate_operand" "")))]
  2613.   "TARGET_80387"
  2614.   "")
  2615.  
  2616. (define_expand "adddf3"
  2617.   [(set (match_operand:DF 0 "register_operand" "")
  2618.     (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2619.          (match_operand:DF 2 "nonimmediate_operand" "")))]
  2620.   "TARGET_80387"
  2621.   "")
  2622.  
  2623. (define_expand "addsf3"
  2624.   [(set (match_operand:SF 0 "register_operand" "")
  2625.     (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2626.          (match_operand:SF 2 "nonimmediate_operand" "")))]
  2627.   "TARGET_80387"
  2628.   "")
  2629.  
  2630. ;;- subtract instructions
  2631.  
  2632. (define_insn "subdi3"
  2633.   [(set (match_operand:DI 0 "general_operand" "=&r,ro,&r,o,o")
  2634.     (minus:DI (match_operand:DI 1 "general_operand" "0,0,roiF,riF,o")
  2635.           (match_operand:DI 2 "general_operand" "o,riF,roiF,riF,o")))
  2636.    (clobber (match_scratch:SI 3 "=X,X,X,X,&r"))]
  2637.   ""
  2638.   "*
  2639. {
  2640.   rtx low[3], high[3], xops[7];
  2641.  
  2642.   CC_STATUS_INIT;
  2643.  
  2644.   split_di (operands, 3, low, high);
  2645.  
  2646.   if (!rtx_equal_p (operands[0], operands[1]))
  2647.     {
  2648.       xops[0] = high[0];
  2649.       xops[1] = low[0];
  2650.       xops[2] = high[1];
  2651.       xops[3] = low[1];
  2652.  
  2653.       if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
  2654.     {
  2655.       output_asm_insn (AS2 (mov%L1,%3,%1), xops);
  2656.       output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  2657.     }
  2658.       else
  2659.     {
  2660.       xops[4] = high[2];
  2661.       xops[5] = low[2];
  2662.       xops[6] = operands[3];
  2663.       output_asm_insn (AS2 (mov%L6,%3,%6), xops);
  2664.       output_asm_insn (AS2 (sub%L6,%5,%6), xops);
  2665.       output_asm_insn (AS2 (mov%L1,%6,%1), xops);
  2666.       output_asm_insn (AS2 (mov%L6,%2,%6), xops);
  2667.       output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
  2668.       output_asm_insn (AS2 (mov%L0,%6,%0), xops);
  2669.       RET;
  2670.     }
  2671.     }
  2672.  
  2673.   if (GET_CODE (operands[3]) == REG)
  2674.     {
  2675.       xops[0] = high[0];
  2676.       xops[1] = low[0];
  2677.       xops[2] = high[2];
  2678.       xops[3] = low[2];
  2679.       xops[4] = operands[3];
  2680.  
  2681.       output_asm_insn (AS2 (mov%L4,%3,%4), xops);
  2682.       output_asm_insn (AS2 (sub%L1,%4,%1), xops);
  2683.       output_asm_insn (AS2 (mov%L4,%2,%4), xops);
  2684.       output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
  2685.     }
  2686.  
  2687.   else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
  2688.     {
  2689.       output_asm_insn (AS2 (sub%L0,%2,%0), low);
  2690.       output_asm_insn (AS2 (sbb%L0,%2,%0), high);
  2691.     }
  2692.  
  2693.   else
  2694.     output_asm_insn (AS2 (sub%L0,%2,%0), high);
  2695.  
  2696.   RET;
  2697. }")
  2698.  
  2699. (define_insn "subsi3"
  2700.   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  2701.     (minus:SI (match_operand:SI 1 "general_operand" "0,0")
  2702.           (match_operand:SI 2 "general_operand" "ri,rm")))]
  2703.   ""
  2704.   "* return AS2 (sub%L0,%2,%0);")
  2705.  
  2706. (define_insn "subhi3"
  2707.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2708.     (minus:HI (match_operand:HI 1 "general_operand" "0,0")
  2709.           (match_operand:HI 2 "general_operand" "ri,rm")))]
  2710.   ""
  2711.   "* return AS2 (sub%W0,%2,%0);")
  2712.  
  2713. (define_insn "subqi3"
  2714.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2715.     (minus:QI (match_operand:QI 1 "general_operand" "0,0")
  2716.           (match_operand:QI 2 "general_operand" "qn,qmn")))]
  2717.   ""
  2718.   "* return AS2 (sub%B0,%2,%0);")
  2719.  
  2720. ;; The patterns that match these are at the end of this file.
  2721.  
  2722. (define_expand "subxf3"
  2723.   [(set (match_operand:XF 0 "register_operand" "")
  2724.     (minus:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2725.           (match_operand:XF 2 "nonimmediate_operand" "")))]
  2726.   "TARGET_80387"
  2727.   "")
  2728.  
  2729. (define_expand "subdf3"
  2730.   [(set (match_operand:DF 0 "register_operand" "")
  2731.     (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2732.           (match_operand:DF 2 "nonimmediate_operand" "")))]
  2733.   "TARGET_80387"
  2734.   "")
  2735.  
  2736. (define_expand "subsf3"
  2737.   [(set (match_operand:SF 0 "register_operand" "")
  2738.     (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2739.           (match_operand:SF 2 "nonimmediate_operand" "")))]
  2740.   "TARGET_80387"
  2741.   "")
  2742.  
  2743. ;;- multiply instructions
  2744.  
  2745. ;(define_insn "mulqi3"
  2746. ;  [(set (match_operand:QI 0 "general_operand" "=a")
  2747. ;    (mult:QI (match_operand:QI 1 "general_operand" "%0")
  2748. ;         (match_operand:QI 2 "general_operand" "qm")))]
  2749. ;  ""
  2750. ;  "imul%B0 %2,%0")
  2751.  
  2752. (define_insn ""
  2753.   [(set (match_operand:HI 0 "general_operand" "=r")
  2754.     (mult:HI (match_operand:HI 1 "general_operand" "%0")
  2755.          (match_operand:HI 2 "general_operand" "r")))]
  2756.   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
  2757.   "* return AS2 (imul%W0,%2,%0);")
  2758.  
  2759. (define_insn "mulhi3"
  2760.   [(set (match_operand:HI 0 "general_operand" "=r,r")
  2761.     (mult:HI (match_operand:HI 1 "general_operand" "%0,rm")
  2762.          (match_operand:HI 2 "general_operand" "g,i")))]
  2763.   ""
  2764.   "*
  2765. {
  2766.   if (GET_CODE (operands[1]) == REG
  2767.       && REGNO (operands[1]) == REGNO (operands[0])
  2768.       && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
  2769.     /* Assembler has weird restrictions.  */
  2770.     return AS2 (imul%W0,%2,%0);
  2771.   return AS3 (imul%W0,%2,%1,%0);
  2772. }")
  2773.  
  2774. (define_insn ""
  2775.   [(set (match_operand:SI 0 "general_operand" "=r")
  2776.     (mult:SI (match_operand:SI 1 "general_operand" "%0")
  2777.          (match_operand:SI 2 "general_operand" "r")))]
  2778.   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
  2779.   "* return AS2 (imul%L0,%2,%0);")
  2780.  
  2781. (define_insn "mulsi3"
  2782.   [(set (match_operand:SI 0 "general_operand" "=r,r")
  2783.     (mult:SI (match_operand:SI 1 "general_operand" "%0,rm")
  2784.          (match_operand:SI 2 "general_operand" "g,i")))]
  2785.   ""
  2786.   "*
  2787. {
  2788.   if (GET_CODE (operands[1]) == REG
  2789.       && REGNO (operands[1]) == REGNO (operands[0])
  2790.       && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
  2791.     /* Assembler has weird restrictions.  */
  2792.     return AS2 (imul%L0,%2,%0);
  2793.   return AS3 (imul%L0,%2,%1,%0);
  2794. }")
  2795.  
  2796. (define_insn "umulqihi3"
  2797.   [(set (match_operand:HI 0 "general_operand" "=a")
  2798.     (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
  2799.          (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
  2800.   ""
  2801.   "mul%B0 %2")
  2802.  
  2803. (define_insn "mulqihi3"
  2804.   [(set (match_operand:HI 0 "general_operand" "=a")
  2805.     (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
  2806.          (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
  2807.   ""
  2808.   "imul%B0 %2")
  2809.  
  2810. (define_insn "umulsidi3"
  2811.   [(set (match_operand:DI 0 "register_operand" "=A")
  2812.     (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
  2813.          (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
  2814.   "TARGET_WIDE_MULTIPLY"
  2815.   "mul%L0 %2")
  2816.  
  2817. (define_insn "mulsidi3"
  2818.   [(set (match_operand:DI 0 "register_operand" "=A")
  2819.     (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
  2820.          (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
  2821.   "TARGET_WIDE_MULTIPLY"
  2822.   "imul%L0 %2")
  2823.  
  2824. (define_insn "umulsi3_highpart"
  2825.   [(set (match_operand:SI 0 "register_operand" "=d")
  2826.     (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
  2827.                        (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
  2828.                   (const_int 32))))
  2829.    (clobber (match_scratch:SI 3 "=a"))]
  2830.   "TARGET_WIDE_MULTIPLY"
  2831.   "mul%L0 %2")
  2832.  
  2833. (define_insn "smulsi3_highpart"
  2834.   [(set (match_operand:SI 0 "register_operand" "=d")
  2835.     (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
  2836.                        (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
  2837.                   (const_int 32))))
  2838.    (clobber (match_scratch:SI 3 "=a"))]
  2839.   "TARGET_WIDE_MULTIPLY"
  2840.   "imul%L0 %2")
  2841.  
  2842. ;; The patterns that match these are at the end of this file.
  2843.  
  2844. (define_expand "mulxf3"
  2845.   [(set (match_operand:XF 0 "register_operand" "")
  2846.     (mult:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2847.          (match_operand:XF 2 "nonimmediate_operand" "")))]
  2848.   "TARGET_80387"
  2849.   "")
  2850.  
  2851. (define_expand "muldf3"
  2852.   [(set (match_operand:DF 0 "register_operand" "")
  2853.     (mult:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2854.          (match_operand:DF 2 "nonimmediate_operand" "")))]
  2855.   "TARGET_80387"
  2856.   "")
  2857.  
  2858. (define_expand "mulsf3"
  2859.   [(set (match_operand:SF 0 "register_operand" "")
  2860.     (mult:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2861.          (match_operand:SF 2 "nonimmediate_operand" "")))]
  2862.   "TARGET_80387"
  2863.   "")
  2864.  
  2865. ;;- divide instructions
  2866.  
  2867. (define_insn "divqi3"
  2868.   [(set (match_operand:QI 0 "general_operand" "=a")
  2869.     (div:QI (match_operand:HI 1 "general_operand" "0")
  2870.         (match_operand:QI 2 "general_operand" "qm")))]
  2871.   ""
  2872.   "idiv%B0 %2")
  2873.  
  2874. (define_insn "udivqi3"
  2875.   [(set (match_operand:QI 0 "general_operand" "=a")
  2876.     (udiv:QI (match_operand:HI 1 "general_operand" "0")
  2877.          (match_operand:QI 2 "general_operand" "qm")))]
  2878.   ""
  2879.   "div%B0 %2")
  2880.  
  2881. ;; The patterns that match these are at the end of this file.
  2882.  
  2883. (define_expand "divxf3"
  2884.   [(set (match_operand:XF 0 "register_operand" "")
  2885.     (div:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2886.         (match_operand:XF 2 "nonimmediate_operand" "")))]
  2887.   "TARGET_80387"
  2888.   "")
  2889.  
  2890. (define_expand "divdf3"
  2891.   [(set (match_operand:DF 0 "register_operand" "")
  2892.     (div:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2893.         (match_operand:DF 2 "nonimmediate_operand" "")))]
  2894.   "TARGET_80387"
  2895.   "")
  2896.  
  2897. (define_expand "divsf3"
  2898.   [(set (match_operand:SF 0 "register_operand" "")
  2899.     (div:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2900.         (match_operand:SF 2 "nonimmediate_operand" "")))]
  2901.   "TARGET_80387"
  2902.   "")
  2903.  
  2904. ;; Remainder instructions.
  2905.  
  2906. (define_insn "divmodsi4"
  2907.   [(set (match_operand:SI 0 "register_operand" "=a")
  2908.     (div:SI (match_operand:SI 1 "register_operand" "0")
  2909.         (match_operand:SI 2 "general_operand" "rm")))
  2910.    (set (match_operand:SI 3 "register_operand" "=&d")
  2911.     (mod:SI (match_dup 1) (match_dup 2)))]
  2912.   ""
  2913.   "*
  2914. {
  2915. #ifdef INTEL_SYNTAX
  2916.   output_asm_insn (\"cdq\", operands);
  2917. #else
  2918.   output_asm_insn (\"cltd\", operands);
  2919. #endif
  2920.   return AS1 (idiv%L0,%2);
  2921. }")
  2922.  
  2923. (define_insn "divmodhi4"
  2924.   [(set (match_operand:HI 0 "register_operand" "=a")
  2925.     (div:HI (match_operand:HI 1 "register_operand" "0")
  2926.         (match_operand:HI 2 "general_operand" "rm")))
  2927.    (set (match_operand:HI 3 "register_operand" "=&d")
  2928.     (mod:HI (match_dup 1) (match_dup 2)))]
  2929.   ""
  2930.   "cwtd\;idiv%W0 %2")
  2931.  
  2932. ;; ??? Can we make gcc zero extend operand[0]?
  2933. (define_insn "udivmodsi4"
  2934.   [(set (match_operand:SI 0 "register_operand" "=a")
  2935.     (udiv:SI (match_operand:SI 1 "register_operand" "0")
  2936.          (match_operand:SI 2 "general_operand" "rm")))
  2937.    (set (match_operand:SI 3 "register_operand" "=&d")
  2938.     (umod:SI (match_dup 1) (match_dup 2)))]
  2939.   ""
  2940.   "*
  2941. {
  2942.   output_asm_insn (AS2 (xor%L3,%3,%3), operands);
  2943.   return AS1 (div%L0,%2);
  2944. }")
  2945.  
  2946. ;; ??? Can we make gcc zero extend operand[0]?
  2947. (define_insn "udivmodhi4"
  2948.   [(set (match_operand:HI 0 "register_operand" "=a")
  2949.     (udiv:HI (match_operand:HI 1 "register_operand" "0")
  2950.          (match_operand:HI 2 "general_operand" "rm")))
  2951.    (set (match_operand:HI 3 "register_operand" "=&d")
  2952.     (umod:HI (match_dup 1) (match_dup 2)))]
  2953.   ""
  2954.   "*
  2955. {
  2956.   output_asm_insn (AS2 (xor%W0,%3,%3), operands);
  2957.   return AS1 (div%W0,%2);
  2958. }")
  2959.  
  2960. /*
  2961. ;;this should be a valid double division which we may want to add
  2962.  
  2963. (define_insn ""
  2964.   [(set (match_operand:SI 0 "register_operand" "=a")
  2965.     (udiv:DI (match_operand:DI 1 "register_operand" "a")
  2966.          (match_operand:SI 2 "general_operand" "rm")))
  2967.    (set (match_operand:SI 3 "register_operand" "=d")
  2968.     (umod:SI (match_dup 1) (match_dup 2)))]
  2969.   ""
  2970.   "div%L0 %2,%0")
  2971. */
  2972.  
  2973. ;;- and instructions
  2974.  
  2975. ;; On i386,
  2976. ;;            movzbl %bl,%ebx
  2977. ;; is faster than
  2978. ;;            andl $255,%ebx
  2979. ;;
  2980. ;; but if the reg is %eax, then the "andl" is faster.
  2981. ;;
  2982. ;; On i486, the "andl" is always faster than the "movzbl".
  2983. ;;
  2984. ;; On both i386 and i486, a three operand AND is as fast with movzbl or
  2985. ;; movzwl as with andl, if operands[0] != operands[1].
  2986.  
  2987. ;; The `r' in `rm' for operand 3 looks redundant, but it causes
  2988. ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
  2989.  
  2990. ;; ??? What if we only change one byte of an offsettable memory reference?
  2991. (define_insn "andsi3"
  2992.   [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r")
  2993.     (and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0")
  2994.         (match_operand:SI 2 "general_operand" "L,K,ri,rm")))]
  2995.   ""
  2996.   "*
  2997. {
  2998.   if (GET_CODE (operands[2]) == CONST_INT
  2999.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  3000.     {
  3001.       if (INTVAL (operands[2]) == 0xffff && REG_P (operands[0])
  3002.       && (! REG_P (operands[1])
  3003.           || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
  3004.       && (TARGET_386 || ! rtx_equal_p (operands[0], operands[1])))
  3005.     {
  3006.       /* ??? tege: Should forget CC_STATUS only if we clobber a
  3007.          remembered operand.  Fix that later.  */
  3008.       CC_STATUS_INIT;
  3009. #ifdef INTEL_SYNTAX
  3010.       return AS2 (movzx,%w1,%0);
  3011. #else
  3012.       return AS2 (movz%W0%L0,%w1,%0);
  3013. #endif
  3014.     }
  3015.  
  3016.       if (INTVAL (operands[2]) == 0xff && REG_P (operands[0])
  3017.       && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
  3018.       && (! REG_P (operands[1])
  3019.           || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
  3020.       && (TARGET_386 || ! rtx_equal_p (operands[0], operands[1])))
  3021.     {
  3022.       /* ??? tege: Should forget CC_STATUS only if we clobber a
  3023.          remembered operand.  Fix that later.  */
  3024.       CC_STATUS_INIT;
  3025. #ifdef INTEL_SYNTAX
  3026.       return AS2 (movzx,%b1,%0);
  3027. #else
  3028.       return AS2 (movz%B0%L0,%b1,%0);
  3029. #endif
  3030.     }
  3031.  
  3032.       if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff) == 0)
  3033.     {
  3034.       CC_STATUS_INIT;
  3035.  
  3036.       if (INTVAL (operands[2]) == 0xffffff00)
  3037.         {
  3038.           operands[2] = const0_rtx;
  3039.           return AS2 (mov%B0,%2,%b0);
  3040.         }
  3041.  
  3042.       operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
  3043.       return AS2 (and%B0,%2,%b0);
  3044.     }
  3045.  
  3046.       if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff00) == 0)
  3047.     {
  3048.       CC_STATUS_INIT;
  3049.  
  3050.       if (INTVAL (operands[2]) == 0xffff00ff)
  3051.         {
  3052.           operands[2] = const0_rtx;
  3053.           return AS2 (mov%B0,%2,%h0);
  3054.         }
  3055.  
  3056.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  3057.       return AS2 (and%B0,%2,%h0);
  3058.     }
  3059.  
  3060.       if (GET_CODE (operands[0]) == MEM && INTVAL (operands[2]) == 0xffff0000)
  3061.         {
  3062.       operands[2] = const0_rtx;
  3063.       return AS2 (mov%W0,%2,%w0);
  3064.     }
  3065.     }
  3066.  
  3067.   return AS2 (and%L0,%2,%0);
  3068. }")
  3069.  
  3070. (define_insn "andhi3"
  3071.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  3072.     (and:HI (match_operand:HI 1 "general_operand" "%0,0")
  3073.         (match_operand:HI 2 "general_operand" "ri,rm")))]
  3074.   ""
  3075.   "*
  3076. {
  3077.   if (GET_CODE (operands[2]) == CONST_INT
  3078.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  3079.     {
  3080.       /* Can we ignore the upper byte? */
  3081.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  3082.       && (INTVAL (operands[2]) & 0xff00) == 0xff00)
  3083.     {
  3084.       CC_STATUS_INIT;
  3085.  
  3086.       if ((INTVAL (operands[2]) & 0xff) == 0)
  3087.         {
  3088.           operands[2] = const0_rtx;
  3089.           return AS2 (mov%B0,%2,%b0);
  3090.         }
  3091.  
  3092.       operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
  3093.       return AS2 (and%B0,%2,%b0);
  3094.     }
  3095.  
  3096.       /* Can we ignore the lower byte? */
  3097.       /* ??? what about offsettable memory references? */
  3098.       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
  3099.     {
  3100.       CC_STATUS_INIT;
  3101.  
  3102.       if ((INTVAL (operands[2]) & 0xff00) == 0)
  3103.         {
  3104.           operands[2] = const0_rtx;
  3105.           return AS2 (mov%B0,%2,%h0);
  3106.         }
  3107.  
  3108.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  3109.       return AS2 (and%B0,%2,%h0);
  3110.     }
  3111.     }
  3112.  
  3113.   return AS2 (and%W0,%2,%0);
  3114. }")
  3115.  
  3116. (define_insn "andqi3"
  3117.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  3118.     (and:QI (match_operand:QI 1 "general_operand" "%0,0")
  3119.         (match_operand:QI 2 "general_operand" "qn,qmn")))]
  3120.   ""
  3121.   "* return AS2 (and%B0,%2,%0);")
  3122.  
  3123. /* I am nervous about these two.. add them later..
  3124. ;I presume this means that we have something in say op0= eax which is small
  3125. ;and we want to and it with memory so we can do this by just an
  3126. ;andb m,%al  and have success.
  3127. (define_insn ""
  3128.   [(set (match_operand:SI 0 "general_operand" "=r")
  3129.     (and:SI (zero_extend:SI
  3130.          (match_operand:HI 1 "nonimmediate_operand" "rm"))
  3131.         (match_operand:SI 2 "general_operand" "0")))]
  3132.   "GET_CODE (operands[2]) == CONST_INT
  3133.    && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
  3134.   "and%W0 %1,%0")
  3135.  
  3136. (define_insn ""
  3137.   [(set (match_operand:SI 0 "general_operand" "=q")
  3138.     (and:SI
  3139.      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
  3140.         (match_operand:SI 2 "general_operand" "0")))]
  3141.   "GET_CODE (operands[2]) == CONST_INT
  3142.    && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
  3143.   "and%L0 %1,%0")
  3144.  
  3145. */
  3146.  
  3147. ;;- Bit set (inclusive or) instructions
  3148.  
  3149. ;; ??? What if we only change one byte of an offsettable memory reference?
  3150. (define_insn "iorsi3"
  3151.   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  3152.     (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
  3153.         (match_operand:SI 2 "general_operand" "ri,rm")))]
  3154.   ""
  3155.   "*
  3156. {
  3157.   if (GET_CODE (operands[2]) == CONST_INT
  3158.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  3159.     {
  3160.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  3161.       && (INTVAL (operands[2]) & ~0xff) == 0)
  3162.     {
  3163.       CC_STATUS_INIT;
  3164.  
  3165.       if (INTVAL (operands[2]) == 0xff)
  3166.         return AS2 (mov%B0,%2,%b0);
  3167.  
  3168.       return AS2 (or%B0,%2,%b0);
  3169.     }
  3170.  
  3171.       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)
  3172.     {
  3173.       CC_STATUS_INIT;
  3174.       operands[2] = GEN_INT (INTVAL (operands[2]) >> 8);
  3175.  
  3176.       if (INTVAL (operands[2]) == 0xff)
  3177.         return AS2 (mov%B0,%2,%h0);
  3178.  
  3179.       return AS2 (or%B0,%2,%h0);
  3180.     }
  3181.     }
  3182.  
  3183.   return AS2 (or%L0,%2,%0);
  3184. }")
  3185.  
  3186. (define_insn "iorhi3"
  3187.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  3188.     (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
  3189.         (match_operand:HI 2 "general_operand" "ri,rm")))]
  3190.   ""
  3191.   "*
  3192. {
  3193.   if (GET_CODE (operands[2]) == CONST_INT
  3194.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  3195.     {
  3196.       /* Can we ignore the upper byte? */
  3197.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  3198.       && (INTVAL (operands[2]) & 0xff00) == 0)
  3199.     {
  3200.       CC_STATUS_INIT;
  3201.       if (INTVAL (operands[2]) & 0xffff0000)
  3202.         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
  3203.  
  3204.       if (INTVAL (operands[2]) == 0xff)
  3205.         return AS2 (mov%B0,%2,%b0);
  3206.  
  3207.       return AS2 (or%B0,%2,%b0);
  3208.     }
  3209.  
  3210.       /* Can we ignore the lower byte? */
  3211.       /* ??? what about offsettable memory references? */
  3212.       if (QI_REG_P (operands[0])
  3213.       && (INTVAL (operands[2]) & 0xff) == 0)
  3214.     {
  3215.       CC_STATUS_INIT;
  3216.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  3217.  
  3218.       if (INTVAL (operands[2]) == 0xff)
  3219.         return AS2 (mov%B0,%2,%h0);
  3220.  
  3221.       return AS2 (or%B0,%2,%h0);
  3222.     }
  3223.     }
  3224.  
  3225.   return AS2 (or%W0,%2,%0);
  3226. }")
  3227.  
  3228. (define_insn "iorqi3"
  3229.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  3230.     (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
  3231.         (match_operand:QI 2 "general_operand" "qn,qmn")))]
  3232.   ""
  3233.   "* return AS2 (or%B0,%2,%0);")
  3234.  
  3235. ;;- xor instructions
  3236.  
  3237. ;; ??? What if we only change one byte of an offsettable memory reference?
  3238. (define_insn "xorsi3"
  3239.   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  3240.     (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
  3241.         (match_operand:SI 2 "general_operand" "ri,rm")))]
  3242.   ""
  3243.   "*
  3244. {
  3245.   if (GET_CODE (operands[2]) == CONST_INT
  3246.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  3247.     {
  3248.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  3249.       && (INTVAL (operands[2]) & ~0xff) == 0)
  3250.     {
  3251.       CC_STATUS_INIT;
  3252.  
  3253.       if (INTVAL (operands[2]) == 0xff)
  3254.         return AS1 (not%B0,%b0);
  3255.  
  3256.       return AS2 (xor%B0,%2,%b0);
  3257.     }
  3258.  
  3259.       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)
  3260.     {
  3261.       CC_STATUS_INIT;
  3262.       operands[2] = GEN_INT (INTVAL (operands[2]) >> 8);
  3263.  
  3264.       if (INTVAL (operands[2]) == 0xff)
  3265.         return AS1 (not%B0,%h0);
  3266.  
  3267.       return AS2 (xor%B0,%2,%h0);
  3268.     }
  3269.     }
  3270.  
  3271.   return AS2 (xor%L0,%2,%0);
  3272. }")
  3273.  
  3274. (define_insn "xorhi3"
  3275.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  3276.     (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
  3277.         (match_operand:HI 2 "general_operand" "ri,rm")))]
  3278.   ""
  3279.   "*
  3280. {
  3281.   if (GET_CODE (operands[2]) == CONST_INT
  3282.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  3283.     {
  3284.       /* Can we ignore the upper byte? */
  3285.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  3286.       && (INTVAL (operands[2]) & 0xff00) == 0)
  3287.     {
  3288.       CC_STATUS_INIT;
  3289.       if (INTVAL (operands[2]) & 0xffff0000)
  3290.         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
  3291.  
  3292.       if (INTVAL (operands[2]) == 0xff)
  3293.         return AS1 (not%B0,%b0);
  3294.  
  3295.       return AS2 (xor%B0,%2,%b0);
  3296.     }
  3297.  
  3298.       /* Can we ignore the lower byte? */
  3299.       /* ??? what about offsettable memory references? */
  3300.       if (QI_REG_P (operands[0])
  3301.       && (INTVAL (operands[2]) & 0xff) == 0)
  3302.     {
  3303.       CC_STATUS_INIT;
  3304.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  3305.  
  3306.       if (INTVAL (operands[2]) == 0xff)
  3307.         return AS1 (not%B0,%h0);
  3308.  
  3309.       return AS2 (xor%B0,%2,%h0);
  3310.     }
  3311.     }
  3312.  
  3313.   return AS2 (xor%W0,%2,%0);
  3314. }")
  3315.  
  3316. (define_insn "xorqi3"
  3317.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  3318.     (xor:QI (match_operand:QI 1 "general_operand" "%0,0")
  3319.         (match_operand:QI 2 "general_operand" "qn,qm")))]
  3320.   ""
  3321.   "* return AS2 (xor%B0,%2,%0);")
  3322.  
  3323. ;;- negation instructions
  3324.  
  3325. (define_insn "negdi2"
  3326.   [(set (match_operand:DI 0 "general_operand" "=&ro")
  3327.     (neg:DI (match_operand:DI 1 "general_operand" "0")))]
  3328.   ""
  3329.   "*
  3330. {
  3331.   rtx xops[2], low[1], high[1];
  3332.  
  3333.   CC_STATUS_INIT;
  3334.  
  3335.   split_di (operands, 1, low, high);
  3336.   xops[0] = const0_rtx;
  3337.   xops[1] = high[0];
  3338.  
  3339.   output_asm_insn (AS1 (neg%L0,%0), low);
  3340.   output_asm_insn (AS2 (adc%L1,%0,%1), xops);
  3341.   output_asm_insn (AS1 (neg%L0,%0), high);
  3342.   RET;
  3343. }")
  3344.  
  3345. (define_insn "negsi2"
  3346.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3347.     (neg:SI (match_operand:SI 1 "general_operand" "0")))]
  3348.   ""
  3349.   "neg%L0 %0")
  3350.  
  3351. (define_insn "neghi2"
  3352.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3353.     (neg:HI (match_operand:HI 1 "general_operand" "0")))]
  3354.   ""
  3355.   "neg%W0 %0")
  3356.  
  3357. (define_insn "negqi2"
  3358.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3359.     (neg:QI (match_operand:QI 1 "general_operand" "0")))]
  3360.   ""
  3361.   "neg%B0 %0")
  3362.  
  3363. (define_insn "negsf2"
  3364.   [(set (match_operand:SF 0 "register_operand" "=f")
  3365.     (neg:SF (match_operand:SF 1 "general_operand" "0")))]
  3366.   "TARGET_80387"
  3367.   "fchs")
  3368.  
  3369. (define_insn "negdf2"
  3370.   [(set (match_operand:DF 0 "register_operand" "=f")
  3371.     (neg:DF (match_operand:DF 1 "general_operand" "0")))]
  3372.   "TARGET_80387"
  3373.   "fchs")
  3374.  
  3375. (define_insn ""
  3376.   [(set (match_operand:DF 0 "register_operand" "=f")
  3377.     (neg:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
  3378.   "TARGET_80387"
  3379.   "fchs")
  3380.  
  3381. (define_insn "negxf2"
  3382.   [(set (match_operand:XF 0 "register_operand" "=f")
  3383.     (neg:XF (match_operand:XF 1 "general_operand" "0")))]
  3384.   "TARGET_80387"
  3385.   "fchs")
  3386.  
  3387. (define_insn ""
  3388.   [(set (match_operand:XF 0 "register_operand" "=f")
  3389.     (neg:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
  3390.   "TARGET_80387"
  3391.   "fchs")
  3392.  
  3393. ;; Absolute value instructions
  3394.  
  3395. (define_insn "abssf2"
  3396.   [(set (match_operand:SF 0 "register_operand" "=f")
  3397.     (abs:SF (match_operand:SF 1 "general_operand" "0")))]
  3398.   "TARGET_80387"
  3399.   "fabs")
  3400.  
  3401. (define_insn "absdf2"
  3402.   [(set (match_operand:DF 0 "register_operand" "=f")
  3403.     (abs:DF (match_operand:DF 1 "general_operand" "0")))]
  3404.   "TARGET_80387"
  3405.   "fabs")
  3406.  
  3407. (define_insn ""
  3408.   [(set (match_operand:DF 0 "register_operand" "=f")
  3409.     (abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
  3410.   "TARGET_80387"
  3411.   "fabs")
  3412.  
  3413. (define_insn "absxf2"
  3414.   [(set (match_operand:XF 0 "register_operand" "=f")
  3415.     (abs:XF (match_operand:XF 1 "general_operand" "0")))]
  3416.   "TARGET_80387"
  3417.   "fabs")
  3418.  
  3419. (define_insn ""
  3420.   [(set (match_operand:XF 0 "register_operand" "=f")
  3421.     (abs:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
  3422.   "TARGET_80387"
  3423.   "fabs")
  3424.  
  3425. (define_insn "sqrtsf2"
  3426.   [(set (match_operand:SF 0 "register_operand" "=f")
  3427.     (sqrt:SF (match_operand:SF 1 "general_operand" "0")))]
  3428.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
  3429.    && (TARGET_IEEE_FP || flag_fast_math) "
  3430.   "fsqrt")
  3431.  
  3432. (define_insn "sqrtdf2"
  3433.   [(set (match_operand:DF 0 "register_operand" "=f")
  3434.     (sqrt:DF (match_operand:DF 1 "general_operand" "0")))]
  3435.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
  3436.    && (TARGET_IEEE_FP || flag_fast_math) "
  3437.   "fsqrt")
  3438.  
  3439. (define_insn ""
  3440.   [(set (match_operand:DF 0 "register_operand" "=f")
  3441.     (sqrt:DF (float_extend:DF
  3442.           (match_operand:SF 1 "general_operand" "0"))))]
  3443.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3444.    && (TARGET_IEEE_FP || flag_fast_math) "
  3445.   "fsqrt")
  3446.  
  3447. (define_insn "sqrtxf2"
  3448.   [(set (match_operand:XF 0 "register_operand" "=f")
  3449.     (sqrt:XF (match_operand:XF 1 "general_operand" "0")))]
  3450.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3451.    && (TARGET_IEEE_FP || flag_fast_math) "
  3452.   "fsqrt")
  3453.  
  3454. (define_insn ""
  3455.   [(set (match_operand:XF 0 "register_operand" "=f")
  3456.     (sqrt:XF (float_extend:XF
  3457.           (match_operand:DF 1 "general_operand" "0"))))]
  3458.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3459.    && (TARGET_IEEE_FP || flag_fast_math) "
  3460.   "fsqrt")
  3461.  
  3462. (define_insn ""
  3463.   [(set (match_operand:XF 0 "register_operand" "=f")
  3464.     (sqrt:XF (float_extend:XF
  3465.           (match_operand:SF 1 "general_operand" "0"))))]
  3466.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3467.    && (TARGET_IEEE_FP || flag_fast_math) "
  3468.   "fsqrt")
  3469.  
  3470. (define_insn "sindf2"
  3471.   [(set (match_operand:DF 0 "register_operand" "=f")
  3472.     (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
  3473.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3474.    && (TARGET_IEEE_FP || flag_fast_math) "
  3475.   "fsin")
  3476.  
  3477. (define_insn "sinsf2"
  3478.   [(set (match_operand:SF 0 "register_operand" "=f")
  3479.     (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
  3480.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3481.    && (TARGET_IEEE_FP || flag_fast_math) "
  3482.   "fsin")
  3483.  
  3484. (define_insn ""
  3485.   [(set (match_operand:DF 0 "register_operand" "=f")
  3486.     (unspec:DF [(float_extend:DF
  3487.              (match_operand:SF 1 "register_operand" "0"))] 1))]
  3488.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3489.    && (TARGET_IEEE_FP || flag_fast_math) "
  3490.   "fsin")
  3491.  
  3492. (define_insn "cosdf2"
  3493.   [(set (match_operand:DF 0 "register_operand" "=f")
  3494.     (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
  3495.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3496.    && (TARGET_IEEE_FP || flag_fast_math) "
  3497.   "fcos")
  3498.  
  3499. (define_insn "cossf2"
  3500.   [(set (match_operand:SF 0 "register_operand" "=f")
  3501.     (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
  3502.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3503.    && (TARGET_IEEE_FP || flag_fast_math) "
  3504.   "fcos")
  3505.  
  3506. (define_insn ""
  3507.   [(set (match_operand:DF 0 "register_operand" "=f")
  3508.     (unspec:DF [(float_extend:DF
  3509.              (match_operand:SF 1 "register_operand" "0"))] 2))]
  3510.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3511.    && (TARGET_IEEE_FP || flag_fast_math) "
  3512.   "fcos")
  3513.  
  3514. ;;- one complement instructions
  3515.  
  3516. (define_insn "one_cmplsi2"
  3517.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3518.     (not:SI (match_operand:SI 1 "general_operand" "0")))]
  3519.   ""
  3520.   "not%L0 %0")
  3521.  
  3522. (define_insn "one_cmplhi2"
  3523.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3524.     (not:HI (match_operand:HI 1 "general_operand" "0")))]
  3525.   ""
  3526.   "not%W0 %0")
  3527.  
  3528. (define_insn "one_cmplqi2"
  3529.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3530.     (not:QI (match_operand:QI 1 "general_operand" "0")))]
  3531.   ""
  3532.   "not%B0 %0")
  3533.  
  3534. ;;- arithmetic shift instructions
  3535.  
  3536. ;; DImode shifts are implemented using the i386 "shift double" opcode,
  3537. ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
  3538. ;; is variable, then the count is in %cl and the "imm" operand is dropped
  3539. ;; from the assembler input.
  3540.  
  3541. ;; This instruction shifts the target reg/mem as usual, but instead of
  3542. ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
  3543. ;; is a left shift double, bits are taken from the high order bits of
  3544. ;; reg, else if the insn is a shift right double, bits are taken from the
  3545. ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
  3546. ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
  3547.  
  3548. ;; Since sh[lr]d does not change the `reg' operand, that is done
  3549. ;; separately, making all shifts emit pairs of shift double and normal
  3550. ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
  3551. ;; support a 63 bit shift, each shift where the count is in a reg expands
  3552. ;; to three pairs.  If the overall shift is by N bits, then the first two
  3553. ;; pairs shift by N / 2 and the last pair by N & 1.
  3554.  
  3555. ;; If the shift count is a constant, we need never emit more than one
  3556. ;; shift pair, instead using moves and sign extension for counts greater
  3557. ;; than 31.
  3558.  
  3559. (define_expand "ashldi3"
  3560.   [(set (match_operand:DI 0 "register_operand" "")
  3561.     (ashift:DI (match_operand:DI 1 "register_operand" "")
  3562.            (match_operand:QI 2 "nonmemory_operand" "")))]
  3563.   ""
  3564.   "
  3565. {
  3566.   if (GET_CODE (operands[2]) != CONST_INT
  3567.       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
  3568.     {
  3569.       operands[2] = copy_to_mode_reg (QImode, operands[2]);
  3570.       emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
  3571.                         operands[2]));
  3572.     }
  3573.   else
  3574.     emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
  3575.  
  3576.   DONE;
  3577. }")
  3578.  
  3579. (define_insn "ashldi3_const_int"
  3580.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3581.     (ashift:DI (match_operand:DI 1 "register_operand" "0")
  3582.            (match_operand:QI 2 "const_int_operand" "J")))]
  3583.   ""
  3584.   "*
  3585. {
  3586.   rtx xops[4], low[1], high[1];
  3587.  
  3588.   CC_STATUS_INIT;
  3589.  
  3590.   split_di (operands, 1, low, high);
  3591.   xops[0] = operands[2];
  3592.   xops[1] = const1_rtx;
  3593.   xops[2] = low[0];
  3594.   xops[3] = high[0];
  3595.  
  3596.   if (INTVAL (xops[0]) > 31)
  3597.     {
  3598.       output_asm_insn (AS2 (mov%L3,%2,%3), xops);    /* Fast shift by 32 */
  3599.       output_asm_insn (AS2 (xor%L2,%2,%2), xops);
  3600.  
  3601.       if (INTVAL (xops[0]) > 32)
  3602.         {
  3603.       xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
  3604.       output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
  3605.     }
  3606.     }
  3607.   else
  3608.     {
  3609.       output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
  3610.       output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3611.     }
  3612.   RET;
  3613. }")
  3614.  
  3615. (define_insn "ashldi3_non_const_int"
  3616.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3617.     (ashift:DI (match_operand:DI 1 "register_operand" "0")
  3618.            (match_operand:QI 2 "register_operand" "c")))
  3619.    (clobber (match_dup 2))]
  3620.   ""
  3621.   "*
  3622. {
  3623.   rtx xops[4], low[1], high[1];
  3624.  
  3625.   CC_STATUS_INIT;
  3626.  
  3627.   split_di (operands, 1, low, high);
  3628.   xops[0] = operands[2];
  3629.   xops[1] = const1_rtx;
  3630.   xops[2] = low[0];
  3631.   xops[3] = high[0];
  3632.  
  3633.   output_asm_insn (AS2 (ror%B0,%1,%0), xops);    /* shift count / 2 */
  3634.  
  3635.   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
  3636.   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3637.   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
  3638.   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3639.  
  3640.   xops[1] = GEN_INT (7);            /* shift count & 1 */
  3641.  
  3642.   output_asm_insn (AS2 (shr%B0,%1,%0), xops);
  3643.  
  3644.   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
  3645.   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3646.  
  3647.   RET;
  3648. }")
  3649.  
  3650. ;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
  3651. ;; On i486, movl/sall appears slightly faster than leal, but the leal
  3652. ;; is smaller - use leal for now unless the shift count is 1.
  3653.  
  3654. (define_insn "ashlsi3"
  3655.   [(set (match_operand:SI 0 "general_operand" "=r,rm")
  3656.     (ashift:SI (match_operand:SI 1 "general_operand" "r,0")
  3657.            (match_operand:SI 2 "nonmemory_operand" "M,cI")))]
  3658.   ""
  3659.   "*
  3660. {
  3661.   if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
  3662.     {
  3663.       if (!TARGET_386 && INTVAL (operands[2]) == 1)
  3664.     {
  3665.       output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  3666.       return AS2 (add%L0,%1,%0);
  3667.     }
  3668.       else
  3669.         {
  3670.           CC_STATUS_INIT;
  3671.  
  3672.       if (operands[1] == stack_pointer_rtx)
  3673.         {
  3674.           output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  3675.           operands[1] = operands[0];
  3676.         }
  3677.           operands[1] = gen_rtx (MULT, SImode, operands[1],
  3678.                  GEN_INT (1 << INTVAL (operands[2])));
  3679.       return AS2 (lea%L0,%a1,%0);
  3680.     }
  3681.     }
  3682.  
  3683.   if (REG_P (operands[2]))
  3684.     return AS2 (sal%L0,%b2,%0);
  3685.  
  3686.   if (REG_P (operands[0]) && operands[2] == const1_rtx)
  3687.     return AS2 (add%L0,%0,%0);
  3688.  
  3689.   return AS2 (sal%L0,%2,%0);
  3690. }")
  3691.  
  3692. (define_insn "ashlhi3"
  3693.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3694.     (ashift:HI (match_operand:HI 1 "general_operand" "0")
  3695.            (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3696.   ""
  3697.   "*
  3698. {
  3699.   if (REG_P (operands[2]))
  3700.     return AS2 (sal%W0,%b2,%0);
  3701.  
  3702.   if (REG_P (operands[0]) && operands[2] == const1_rtx)
  3703.     return AS2 (add%W0,%0,%0);
  3704.  
  3705.   return AS2 (sal%W0,%2,%0);
  3706. }")
  3707.  
  3708. (define_insn "ashlqi3"
  3709.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3710.     (ashift:QI (match_operand:QI 1 "general_operand" "0")
  3711.            (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3712.   ""
  3713.   "*
  3714. {
  3715.   if (REG_P (operands[2]))
  3716.     return AS2 (sal%B0,%b2,%0);
  3717.  
  3718.   if (REG_P (operands[0]) && operands[2] == const1_rtx)
  3719.     return AS2 (add%B0,%0,%0);
  3720.  
  3721.   return AS2 (sal%B0,%2,%0);
  3722. }")
  3723.  
  3724. ;; See comment above `ashldi3' about how this works.
  3725.  
  3726. (define_expand "ashrdi3"
  3727.   [(set (match_operand:DI 0 "register_operand" "")
  3728.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
  3729.              (match_operand:QI 2 "nonmemory_operand" "")))]
  3730.   ""
  3731.   "
  3732. {
  3733.   if (GET_CODE (operands[2]) != CONST_INT
  3734.       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
  3735.     {
  3736.       operands[2] = copy_to_mode_reg (QImode, operands[2]);
  3737.       emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1],
  3738.                         operands[2]));
  3739.     }
  3740.   else
  3741.     emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2]));
  3742.  
  3743.   DONE;
  3744. }")
  3745.  
  3746. (define_insn "ashrdi3_const_int"
  3747.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3748.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3749.              (match_operand:QI 2 "const_int_operand" "J")))]
  3750.   ""
  3751.   "*
  3752. {
  3753.   rtx xops[4], low[1], high[1];
  3754.  
  3755.   CC_STATUS_INIT;
  3756.  
  3757.   split_di (operands, 1, low, high);
  3758.   xops[0] = operands[2];
  3759.   xops[1] = const1_rtx;
  3760.   xops[2] = low[0];
  3761.   xops[3] = high[0];
  3762.  
  3763.   if (INTVAL (xops[0]) > 31)
  3764.     {
  3765.       xops[1] = GEN_INT (31);
  3766.       output_asm_insn (AS2 (mov%L2,%3,%2), xops);
  3767.       output_asm_insn (AS2 (sar%L3,%1,%3), xops);    /* shift by 32 */
  3768.  
  3769.       if (INTVAL (xops[0]) > 32)
  3770.         {
  3771.       xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
  3772.       output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */
  3773.     }
  3774.     }
  3775.   else
  3776.     {
  3777.       output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
  3778.       output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3779.     }
  3780.  
  3781.   RET;
  3782. }")
  3783.  
  3784. (define_insn "ashrdi3_non_const_int"
  3785.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3786.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3787.              (match_operand:QI 2 "register_operand" "c")))
  3788.    (clobber (match_dup 2))]
  3789.   ""
  3790.   "*
  3791. {
  3792.   rtx xops[4], low[1], high[1];
  3793.  
  3794.   CC_STATUS_INIT;
  3795.  
  3796.   split_di (operands, 1, low, high);
  3797.   xops[0] = operands[2];
  3798.   xops[1] = const1_rtx;
  3799.   xops[2] = low[0];
  3800.   xops[3] = high[0];
  3801.  
  3802.   output_asm_insn (AS2 (ror%B0,%1,%0), xops);    /* shift count / 2 */
  3803.  
  3804.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3805.   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3806.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3807.   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3808.  
  3809.   xops[1] = GEN_INT (7);            /* shift count & 1 */
  3810.  
  3811.   output_asm_insn (AS2 (shr%B0,%1,%0), xops);
  3812.  
  3813.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3814.   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3815.  
  3816.   RET;
  3817. }")
  3818.  
  3819. (define_insn "ashrsi3"
  3820.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3821.     (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
  3822.              (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3823.   ""
  3824.   "*
  3825. {
  3826.   if (REG_P (operands[2]))
  3827.     return AS2 (sar%L0,%b2,%0);
  3828.   else
  3829.     return AS2 (sar%L0,%2,%0);
  3830. }")
  3831.  
  3832. (define_insn "ashrhi3"
  3833.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3834.     (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
  3835.              (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3836.   ""
  3837.   "*
  3838. {
  3839.   if (REG_P (operands[2]))
  3840.     return AS2 (sar%W0,%b2,%0);
  3841.   else
  3842.     return AS2 (sar%W0,%2,%0);
  3843. }")
  3844.  
  3845. (define_insn "ashrqi3"
  3846.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3847.     (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
  3848.              (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3849.   ""
  3850.   "*
  3851. {
  3852.   if (REG_P (operands[2]))
  3853.     return AS2 (sar%B0,%b2,%0);
  3854.   else
  3855.     return AS2 (sar%B0,%2,%0);
  3856. }")
  3857.  
  3858. ;;- logical shift instructions
  3859.  
  3860. ;; See comment above `ashldi3' about how this works.
  3861.  
  3862. (define_expand "lshrdi3"
  3863.   [(set (match_operand:DI 0 "register_operand" "")
  3864.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
  3865.              (match_operand:QI 2 "nonmemory_operand" "")))]
  3866.   ""
  3867.   "
  3868. {
  3869.   if (GET_CODE (operands[2]) != CONST_INT
  3870.       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
  3871.     {
  3872.       operands[2] = copy_to_mode_reg (QImode, operands[2]);
  3873.       emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
  3874.                         operands[2]));
  3875.     }
  3876.   else
  3877.     emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
  3878.  
  3879.   DONE;
  3880. }")
  3881.  
  3882. (define_insn "lshrdi3_const_int"
  3883.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3884.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3885.              (match_operand:QI 2 "const_int_operand" "J")))]
  3886.   ""
  3887.   "*
  3888. {
  3889.   rtx xops[4], low[1], high[1];
  3890.  
  3891.   CC_STATUS_INIT;
  3892.  
  3893.   split_di (operands, 1, low, high);
  3894.   xops[0] = operands[2];
  3895.   xops[1] = const1_rtx;
  3896.   xops[2] = low[0];
  3897.   xops[3] = high[0];
  3898.  
  3899.   if (INTVAL (xops[0]) > 31)
  3900.     {
  3901.       output_asm_insn (AS2 (mov%L2,%3,%2), xops);    /* Fast shift by 32 */
  3902.       output_asm_insn (AS2 (xor%L3,%3,%3), xops);
  3903.  
  3904.       if (INTVAL (xops[0]) > 32)
  3905.         {
  3906.       xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
  3907.       output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
  3908.     }
  3909.     }
  3910.   else
  3911.     {
  3912.       output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
  3913.       output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3914.     }
  3915.  
  3916.   RET;
  3917. }")
  3918.  
  3919. (define_insn "lshrdi3_non_const_int"
  3920.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3921.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3922.              (match_operand:QI 2 "register_operand" "c")))
  3923.    (clobber (match_dup 2))]
  3924.   ""
  3925.   "*
  3926. {
  3927.   rtx xops[4], low[1], high[1];
  3928.  
  3929.   CC_STATUS_INIT;
  3930.  
  3931.   split_di (operands, 1, low, high);
  3932.   xops[0] = operands[2];
  3933.   xops[1] = const1_rtx;
  3934.   xops[2] = low[0];
  3935.   xops[3] = high[0];
  3936.  
  3937.   output_asm_insn (AS2 (ror%B0,%1,%0), xops);    /* shift count / 2 */
  3938.  
  3939.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3940.   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3941.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3942.   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3943.  
  3944.   xops[1] = GEN_INT (7);            /* shift count & 1 */
  3945.  
  3946.   output_asm_insn (AS2 (shr%B0,%1,%0), xops);
  3947.  
  3948.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3949.   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3950.  
  3951.   RET;
  3952. }")
  3953.  
  3954. (define_insn "lshrsi3"
  3955.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3956.     (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
  3957.              (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3958.   ""
  3959.   "*
  3960. {
  3961.   if (REG_P (operands[2]))
  3962.     return AS2 (shr%L0,%b2,%0);
  3963.   else
  3964.     return AS2 (shr%L0,%2,%1);
  3965. }")
  3966.  
  3967. (define_insn "lshrhi3"
  3968.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3969.     (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
  3970.              (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3971.   ""
  3972.   "*
  3973. {
  3974.   if (REG_P (operands[2]))
  3975.     return AS2 (shr%W0,%b2,%0);
  3976.   else
  3977.     return AS2 (shr%W0,%2,%0);
  3978. }")
  3979.  
  3980. (define_insn "lshrqi3"
  3981.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3982.     (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
  3983.              (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3984.   ""
  3985.   "*
  3986. {
  3987.   if (REG_P (operands[2]))
  3988.     return AS2 (shr%B0,%b2,%0);
  3989.   else
  3990.     return AS2 (shr%B0,%2,%0);
  3991. }")
  3992.  
  3993. ;;- rotate instructions
  3994.  
  3995. (define_insn "rotlsi3"
  3996.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3997.     (rotate:SI (match_operand:SI 1 "general_operand" "0")
  3998.            (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3999.   ""
  4000.   "*
  4001. {
  4002.   if (REG_P (operands[2]))
  4003.     return AS2 (rol%L0,%b2,%0);
  4004.   else
  4005.     return AS2 (rol%L0,%2,%0);
  4006. }")
  4007.  
  4008. (define_insn "rotlhi3"
  4009.   [(set (match_operand:HI 0 "general_operand" "=rm")
  4010.     (rotate:HI (match_operand:HI 1 "general_operand" "0")
  4011.            (match_operand:HI 2 "nonmemory_operand" "cI")))]
  4012.   ""
  4013.   "*
  4014. {
  4015.   if (REG_P (operands[2]))
  4016.     return AS2 (rol%W0,%b2,%0);
  4017.   else
  4018.     return AS2 (rol%W0,%2,%0);
  4019. }")
  4020.  
  4021. (define_insn "rotlqi3"
  4022.   [(set (match_operand:QI 0 "general_operand" "=qm")
  4023.     (rotate:QI (match_operand:QI 1 "general_operand" "0")
  4024.            (match_operand:QI 2 "nonmemory_operand" "cI")))]
  4025.   ""
  4026.   "*
  4027. {
  4028.   if (REG_P (operands[2]))
  4029.     return AS2 (rol%B0,%b2,%0);
  4030.   else
  4031.     return AS2 (rol%B0,%2,%0);
  4032. }")
  4033.  
  4034. (define_insn "rotrsi3"
  4035.   [(set (match_operand:SI 0 "general_operand" "=rm")
  4036.     (rotatert:SI (match_operand:SI 1 "general_operand" "0")
  4037.              (match_operand:SI 2 "nonmemory_operand" "cI")))]
  4038.   ""
  4039.   "*
  4040. {
  4041.   if (REG_P (operands[2]))
  4042.     return AS2 (ror%L0,%b2,%0);
  4043.   else
  4044.     return AS2 (ror%L0,%2,%0);
  4045. }")
  4046.  
  4047. (define_insn "rotrhi3"
  4048.   [(set (match_operand:HI 0 "general_operand" "=rm")
  4049.     (rotatert:HI (match_operand:HI 1 "general_operand" "0")
  4050.              (match_operand:HI 2 "nonmemory_operand" "cI")))]
  4051.   ""
  4052.   "*
  4053. {
  4054.   if (REG_P (operands[2]))
  4055.     return AS2 (ror%W0,%b2,%0);
  4056.   else
  4057.     return AS2 (ror%W0,%2,%0);
  4058. }")
  4059.  
  4060. (define_insn "rotrqi3"
  4061.   [(set (match_operand:QI 0 "general_operand" "=qm")
  4062.     (rotatert:QI (match_operand:QI 1 "general_operand" "0")
  4063.              (match_operand:QI 2 "nonmemory_operand" "cI")))]
  4064.   ""
  4065.   "*
  4066. {
  4067.   if (REG_P (operands[2]))
  4068.     return AS2 (ror%B0,%b2,%0);
  4069.   else
  4070.     return AS2 (ror%B0,%2,%0);
  4071. }")
  4072.  
  4073. /*
  4074. ;; This usually looses.  But try a define_expand to recognize a few case
  4075. ;; we can do efficiently, such as accessing the "high" QImode registers,
  4076. ;; %ah, %bh, %ch, %dh.
  4077. (define_insn "insv"
  4078.   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
  4079.              (match_operand:SI 1 "general_operand" "i")
  4080.              (match_operand:SI 2 "general_operand" "i"))
  4081.     (match_operand:SI 3 "general_operand" "ri"))]
  4082.   ""
  4083.   "*
  4084. {
  4085.   if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
  4086.     abort ();
  4087.   if (GET_CODE (operands[3]) == CONST_INT)
  4088.     {
  4089.       unsigned int mask = (1 << INTVAL (operands[1])) - 1; 
  4090.       operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
  4091.       output_asm_insn (AS2 (and%L0,%1,%0), operands);
  4092.       operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
  4093.       output_asm_insn (AS2 (or%L0,%3,%0), operands);
  4094.     }
  4095.   else
  4096.     {
  4097.       operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
  4098.       if (INTVAL (operands[2]))
  4099.     output_asm_insn (AS2 (ror%L0,%2,%0), operands);
  4100.       output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
  4101.       operands[2] = GEN_INT (BITS_PER_WORD
  4102.                  - INTVAL (operands[1]) - INTVAL (operands[2]));
  4103.       if (INTVAL (operands[2]))
  4104.     output_asm_insn (AS2 (ror%L0,%2,%0), operands);
  4105.     }
  4106.   RET;
  4107. }")
  4108. */
  4109. /*
  4110. ;; ??? There are problems with the mode of operand[3].  The point of this
  4111. ;; is to represent an HImode move to a "high byte" register.
  4112.  
  4113. (define_expand "insv"
  4114.   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
  4115.              (match_operand:SI 1 "immediate_operand" "")
  4116.              (match_operand:SI 2 "immediate_operand" ""))
  4117.     (match_operand:QI 3 "general_operand" "ri"))]
  4118.   ""
  4119.   "
  4120. {
  4121.   if (GET_CODE (operands[1]) != CONST_INT
  4122.       || GET_CODE (operands[2]) != CONST_INT)
  4123.     FAIL;
  4124.  
  4125.   if (! (INTVAL (operands[1]) == 8
  4126.      && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
  4127.       && ! INTVAL (operands[1]) == 1)
  4128.     FAIL;
  4129. }")
  4130.  
  4131. ;; ??? Are these constraints right?
  4132. (define_insn ""
  4133.   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+&qo")
  4134.              (const_int 8)
  4135.              (const_int 8))
  4136.     (match_operand:QI 1 "general_operand" "qn"))]
  4137.   ""
  4138.   "*
  4139. {
  4140.   if (REG_P (operands[0]))
  4141.     return AS2 (mov%B0,%1,%h0);
  4142.  
  4143.   operands[0] = adj_offsettable_operand (operands[0], 1);
  4144.   return AS2 (mov%B0,%1,%0);
  4145. }")
  4146. */
  4147.  
  4148. ;; On i386, the register count for a bit operation is *not* truncated,
  4149. ;; so SHIFT_COUNT_TRUNCATED must not be defined.
  4150.  
  4151. ;; On i486, the shift & or/and code is faster than bts or btr.  If
  4152. ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
  4153.  
  4154. ;; On i386, bts is a little faster if operands[0] is a reg, and a
  4155. ;; little slower if operands[0] is a MEM, than the shift & or/and code.
  4156. ;; Use bts & btr, since they reload better.
  4157.  
  4158. ;; General bit set and clear.
  4159. (define_insn ""
  4160.   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+rm")
  4161.              (const_int 1)
  4162.              (match_operand:SI 2 "general_operand" "r"))
  4163.     (match_operand:SI 3 "const_int_operand" "n"))]
  4164.   "TARGET_386 && GET_CODE (operands[2]) != CONST_INT"
  4165.   "*
  4166. {
  4167.   CC_STATUS_INIT;
  4168.  
  4169.   if (INTVAL (operands[3]) == 1)
  4170.     return AS2 (bts%L0,%2,%0);
  4171.   else
  4172.     return AS2 (btr%L0,%2,%0);
  4173. }")
  4174.  
  4175. ;; Bit complement.  See comments on previous pattern.
  4176. ;; ??? Is this really worthwhile?
  4177. (define_insn ""
  4178.   [(set (match_operand:SI 0 "general_operand" "=rm")
  4179.     (xor:SI (ashift:SI (const_int 1)
  4180.                (match_operand:SI 1 "general_operand" "r"))
  4181.         (match_operand:SI 2 "general_operand" "0")))]
  4182.   "TARGET_386 && GET_CODE (operands[1]) != CONST_INT"
  4183.   "*
  4184. {
  4185.   CC_STATUS_INIT;
  4186.  
  4187.   return AS2 (btc%L0,%1,%0);
  4188. }")
  4189.  
  4190. (define_insn ""
  4191.   [(set (match_operand:SI 0 "general_operand" "=rm")
  4192.     (xor:SI (match_operand:SI 1 "general_operand" "0")
  4193.         (ashift:SI (const_int 1)
  4194.                (match_operand:SI 2 "general_operand" "r"))))]
  4195.   "TARGET_386 && GET_CODE (operands[2]) != CONST_INT"
  4196.   "*
  4197. {
  4198.   CC_STATUS_INIT;
  4199.  
  4200.   return AS2 (btc%L0,%2,%0);
  4201. }")
  4202.  
  4203. ;; Recognizers for bit-test instructions.
  4204.  
  4205. ;; The bt opcode allows a MEM in operands[0].  But on both i386 and
  4206. ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
  4207. ;; bt on the MEM directly.
  4208.  
  4209. ;; ??? The first argument of a zero_extract must not be reloaded, so
  4210. ;; don't allow a MEM in the operand predicate without allowing it in the
  4211. ;; constraint.
  4212.  
  4213. (define_insn ""
  4214.   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
  4215.                 (const_int 1)
  4216.                 (match_operand:SI 1 "general_operand" "r")))]
  4217.   "GET_CODE (operands[1]) != CONST_INT"
  4218.   "*
  4219. {
  4220.   cc_status.flags |= CC_Z_IN_NOT_C;
  4221.   return AS2 (bt%L0,%1,%0);
  4222. }")
  4223.  
  4224. (define_insn ""
  4225.   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
  4226.                 (match_operand:SI 1 "const_int_operand" "n")
  4227.                 (match_operand:SI 2 "const_int_operand" "n")))]
  4228.   ""
  4229.   "*
  4230. {
  4231.   unsigned int mask;
  4232.  
  4233.   mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
  4234.   operands[1] = GEN_INT (mask);
  4235.  
  4236.   if (QI_REG_P (operands[0]))
  4237.     {
  4238.       if ((mask & ~0xff) == 0)
  4239.         {
  4240.       cc_status.flags |= CC_NOT_NEGATIVE;
  4241.       return AS2 (test%B0,%1,%b0);
  4242.     }
  4243.  
  4244.       if ((mask & ~0xff00) == 0)
  4245.         {
  4246.       cc_status.flags |= CC_NOT_NEGATIVE;
  4247.       operands[1] = GEN_INT (mask >> 8);
  4248.       return AS2 (test%B0,%1,%h0);
  4249.     }
  4250.     }
  4251.  
  4252.   return AS2 (test%L0,%1,%0);
  4253. }")
  4254.  
  4255. ;; ??? All bets are off if operand 0 is a volatile MEM reference.
  4256. ;; The CPU may access unspecified bytes around the actual target byte.
  4257.  
  4258. (define_insn ""
  4259.   [(set (cc0) (zero_extract (match_operand:QI 0 "general_operand" "rm")
  4260.                 (match_operand:SI 1 "const_int_operand" "n")
  4261.                 (match_operand:SI 2 "const_int_operand" "n")))]
  4262.   "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
  4263.   "*
  4264. {
  4265.   unsigned int mask;
  4266.  
  4267.   mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
  4268.   operands[1] = GEN_INT (mask);
  4269.  
  4270.   if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
  4271.     {
  4272.       if ((mask & ~0xff) == 0)
  4273.         {
  4274.       cc_status.flags |= CC_NOT_NEGATIVE;
  4275.       return AS2 (test%B0,%1,%b0);
  4276.     }
  4277.  
  4278.       if ((mask & ~0xff00) == 0)
  4279.         {
  4280.       cc_status.flags |= CC_NOT_NEGATIVE;
  4281.       operands[1] = GEN_INT (mask >> 8);
  4282.  
  4283.       if (QI_REG_P (operands[0]))
  4284.         return AS2 (test%B0,%1,%h0);
  4285.       else
  4286.         {
  4287.           operands[0] = adj_offsettable_operand (operands[0], 1);
  4288.           return AS2 (test%B0,%1,%b0);
  4289.         }
  4290.     }
  4291.  
  4292.       if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
  4293.         {
  4294.       cc_status.flags |= CC_NOT_NEGATIVE;
  4295.       operands[1] = GEN_INT (mask >> 16);
  4296.       operands[0] = adj_offsettable_operand (operands[0], 2);
  4297.       return AS2 (test%B0,%1,%b0);
  4298.     }
  4299.  
  4300.       if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
  4301.         {
  4302.       cc_status.flags |= CC_NOT_NEGATIVE;
  4303.       operands[1] = GEN_INT (mask >> 24);
  4304.       operands[0] = adj_offsettable_operand (operands[0], 3);
  4305.       return AS2 (test%B0,%1,%b0);
  4306.     }
  4307.     }
  4308.  
  4309.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  4310.     return AS2 (test%L0,%1,%0);
  4311.  
  4312.   return AS2 (test%L1,%0,%1);
  4313. }")
  4314.  
  4315. ;; Store-flag instructions.
  4316.  
  4317. ;; For all sCOND expanders, also expand the compare or test insn that
  4318. ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
  4319.  
  4320. ;; The 386 sCOND opcodes can write to memory.  But a gcc sCOND insn may
  4321. ;; not have any input reloads.  A MEM write might need an input reload
  4322. ;; for the address of the MEM.  So don't allow MEM as the SET_DEST.
  4323.  
  4324. (define_expand "seq"
  4325.   [(match_dup 1)
  4326.    (set (match_operand:QI 0 "register_operand" "")
  4327.     (eq:QI (cc0) (const_int 0)))]
  4328.   ""
  4329.   "
  4330. {
  4331.   if (TARGET_IEEE_FP
  4332.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  4333.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  4334.   else
  4335.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  4336. }")
  4337.  
  4338. (define_insn ""
  4339.   [(set (match_operand:QI 0 "register_operand" "=q")
  4340.     (eq:QI (cc0) (const_int 0)))]
  4341.   ""
  4342.   "*
  4343. {
  4344.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4345.     return AS1 (setnb,%0);
  4346.   else
  4347.     return AS1 (sete,%0);
  4348. }")
  4349.  
  4350. (define_expand "sne"
  4351.   [(match_dup 1)
  4352.    (set (match_operand:QI 0 "register_operand" "")
  4353.     (ne:QI (cc0) (const_int 0)))]
  4354.   ""
  4355.   "
  4356. {
  4357.   if (TARGET_IEEE_FP
  4358.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  4359.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  4360.   else
  4361.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  4362. }")
  4363.  
  4364. (define_insn ""
  4365.   [(set (match_operand:QI 0 "register_operand" "=q")
  4366.     (ne:QI (cc0) (const_int 0)))]
  4367.   ""
  4368.   "*
  4369. {
  4370.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4371.     return AS1 (setb,%0);
  4372.   else
  4373.     return AS1 (setne,%0);
  4374. }
  4375. ")
  4376.  
  4377. (define_expand "sgt"
  4378.   [(match_dup 1)
  4379.    (set (match_operand:QI 0 "register_operand" "")
  4380.     (gt:QI (cc0) (const_int 0)))]
  4381.   ""
  4382.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4383.  
  4384. (define_insn ""
  4385.   [(set (match_operand:QI 0 "register_operand" "=q")
  4386.     (gt:QI (cc0) (const_int 0)))]
  4387.   ""
  4388.   "*
  4389. {
  4390.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4391.     return AS1 (sete,%0);
  4392.  
  4393.   OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR);
  4394. }")
  4395.  
  4396. (define_expand "sgtu"
  4397.   [(match_dup 1)
  4398.    (set (match_operand:QI 0 "register_operand" "")
  4399.     (gtu:QI (cc0) (const_int 0)))]
  4400.   ""
  4401.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4402.  
  4403. (define_insn ""
  4404.   [(set (match_operand:QI 0 "register_operand" "=q")
  4405.     (gtu:QI (cc0) (const_int 0)))]
  4406.   ""
  4407.   "* return \"seta %0\"; ")
  4408.  
  4409. (define_expand "slt"
  4410.   [(match_dup 1)
  4411.    (set (match_operand:QI 0 "register_operand" "")
  4412.     (lt:QI (cc0) (const_int 0)))]
  4413.   ""
  4414.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4415.  
  4416. (define_insn ""
  4417.   [(set (match_operand:QI 0 "register_operand" "=q")
  4418.     (lt:QI (cc0) (const_int 0)))]
  4419.   ""
  4420.   "*
  4421. {
  4422.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4423.     return AS1 (sete,%0);
  4424.  
  4425.   OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\");
  4426. }")
  4427.  
  4428. (define_expand "sltu"
  4429.   [(match_dup 1)
  4430.    (set (match_operand:QI 0 "register_operand" "")
  4431.     (ltu:QI (cc0) (const_int 0)))]
  4432.   ""
  4433.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4434.  
  4435. (define_insn ""
  4436.   [(set (match_operand:QI 0 "register_operand" "=q")
  4437.     (ltu:QI (cc0) (const_int 0)))]
  4438.   ""
  4439.   "* return \"setb %0\"; ")
  4440.  
  4441. (define_expand "sge"
  4442.   [(match_dup 1)
  4443.    (set (match_operand:QI 0 "register_operand" "")
  4444.     (ge:QI (cc0) (const_int 0)))]
  4445.   ""
  4446.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4447.  
  4448. (define_insn ""
  4449.   [(set (match_operand:QI 0 "register_operand" "=q")
  4450.     (ge:QI (cc0) (const_int 0)))]
  4451.   ""
  4452.   "*
  4453. {
  4454.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4455.     return AS1 (sete,%0);
  4456.  
  4457.   OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\");
  4458. }")
  4459.  
  4460. (define_expand "sgeu"
  4461.   [(match_dup 1)
  4462.    (set (match_operand:QI 0 "register_operand" "")
  4463.     (geu:QI (cc0) (const_int 0)))]
  4464.   ""
  4465.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4466.  
  4467. (define_insn ""
  4468.   [(set (match_operand:QI 0 "register_operand" "=q")
  4469.     (geu:QI (cc0) (const_int 0)))]
  4470.   ""
  4471.   "* return \"setae %0\"; ")
  4472.  
  4473. (define_expand "sle"
  4474.   [(match_dup 1)
  4475.    (set (match_operand:QI 0 "register_operand" "")
  4476.     (le:QI (cc0) (const_int 0)))]
  4477.   ""
  4478.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4479.  
  4480. (define_insn ""
  4481.   [(set (match_operand:QI 0 "register_operand" "=q")
  4482.     (le:QI (cc0) (const_int 0)))]
  4483.   ""
  4484.   "*
  4485. {
  4486.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4487.     return AS1 (setb,%0);
  4488.  
  4489.   OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR);
  4490. }")
  4491.  
  4492. (define_expand "sleu"
  4493.   [(match_dup 1)
  4494.    (set (match_operand:QI 0 "register_operand" "")
  4495.     (leu:QI (cc0) (const_int 0)))]
  4496.   ""
  4497.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4498.  
  4499. (define_insn ""
  4500.   [(set (match_operand:QI 0 "register_operand" "=q")
  4501.     (leu:QI (cc0) (const_int 0)))]
  4502.   ""
  4503.   "* return \"setbe %0\"; ")
  4504.  
  4505. ;; Basic conditional jump instructions.
  4506. ;; We ignore the overflow flag for signed branch instructions.
  4507.  
  4508. ;; For all bCOND expanders, also expand the compare or test insn that
  4509. ;; generates cc0.  Generate an equality comparison if `beq' or `bne'.
  4510.  
  4511. (define_expand "beq"
  4512.   [(match_dup 1)
  4513.    (set (pc)
  4514.     (if_then_else (eq (cc0)
  4515.               (const_int 0))
  4516.               (label_ref (match_operand 0 "" ""))
  4517.               (pc)))]
  4518.   ""
  4519.   "
  4520. {
  4521.   if (TARGET_IEEE_FP
  4522.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  4523.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  4524.   else
  4525.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  4526. }")
  4527.  
  4528. (define_insn ""
  4529.   [(set (pc)
  4530.     (if_then_else (eq (cc0)
  4531.               (const_int 0))
  4532.               (label_ref (match_operand 0 "" ""))
  4533.               (pc)))]
  4534.   ""
  4535.   "*
  4536. {
  4537.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4538.     return \"jnc %l0\";
  4539.   else
  4540.     return \"je %l0\";
  4541. }")
  4542.  
  4543. (define_expand "bne"
  4544.   [(match_dup 1)
  4545.    (set (pc)
  4546.     (if_then_else (ne (cc0)
  4547.               (const_int 0))
  4548.               (label_ref (match_operand 0 "" ""))
  4549.               (pc)))]
  4550.   ""
  4551.   "
  4552. {
  4553.   if (TARGET_IEEE_FP
  4554.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  4555.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  4556.   else
  4557.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  4558. }")
  4559.  
  4560. (define_insn ""
  4561.   [(set (pc)
  4562.     (if_then_else (ne (cc0)
  4563.               (const_int 0))
  4564.               (label_ref (match_operand 0 "" ""))
  4565.               (pc)))]
  4566.   ""
  4567.   "*
  4568. {
  4569.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4570.     return \"jc %l0\";
  4571.   else
  4572.     return \"jne %l0\";
  4573. }")
  4574.  
  4575. (define_expand "bgt"
  4576.   [(match_dup 1)
  4577.    (set (pc)
  4578.     (if_then_else (gt (cc0)
  4579.               (const_int 0))
  4580.               (label_ref (match_operand 0 "" ""))
  4581.               (pc)))]
  4582.   ""
  4583.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4584.  
  4585. (define_insn ""
  4586.   [(set (pc)
  4587.     (if_then_else (gt (cc0)
  4588.               (const_int 0))
  4589.               (label_ref (match_operand 0 "" ""))
  4590.               (pc)))]
  4591.   ""
  4592.   "*
  4593. {
  4594.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4595.     return AS1 (je,%l0);
  4596.  
  4597.   OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
  4598. }")
  4599.  
  4600. (define_expand "bgtu"
  4601.   [(match_dup 1)
  4602.    (set (pc)
  4603.     (if_then_else (gtu (cc0)
  4604.                (const_int 0))
  4605.               (label_ref (match_operand 0 "" ""))
  4606.               (pc)))]
  4607.   ""
  4608.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4609.  
  4610. (define_insn ""
  4611.   [(set (pc)
  4612.     (if_then_else (gtu (cc0)
  4613.                (const_int 0))
  4614.               (label_ref (match_operand 0 "" ""))
  4615.               (pc)))]
  4616.   ""
  4617.   "ja %l0")
  4618.  
  4619. (define_expand "blt"
  4620.   [(match_dup 1)
  4621.    (set (pc)
  4622.     (if_then_else (lt (cc0)
  4623.               (const_int 0))
  4624.               (label_ref (match_operand 0 "" ""))
  4625.               (pc)))]
  4626.   ""
  4627.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4628.  
  4629. (define_insn ""
  4630.   [(set (pc)
  4631.     (if_then_else (lt (cc0)
  4632.               (const_int 0))
  4633.               (label_ref (match_operand 0 "" ""))
  4634.               (pc)))]
  4635.   ""
  4636.   "*
  4637. {
  4638.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4639.     return AS1 (je,%l0);
  4640.  
  4641.   OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  4642. }")
  4643.  
  4644. (define_expand "bltu"
  4645.   [(match_dup 1)
  4646.    (set (pc)
  4647.     (if_then_else (ltu (cc0)
  4648.                (const_int 0))
  4649.               (label_ref (match_operand 0 "" ""))
  4650.               (pc)))]
  4651.   ""
  4652.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4653.  
  4654. (define_insn ""
  4655.   [(set (pc)
  4656.     (if_then_else (ltu (cc0)
  4657.                (const_int 0))
  4658.               (label_ref (match_operand 0 "" ""))
  4659.               (pc)))]
  4660.   ""
  4661.   "jb %l0")
  4662.  
  4663. (define_expand "bge"
  4664.   [(match_dup 1)
  4665.    (set (pc)
  4666.     (if_then_else (ge (cc0)
  4667.               (const_int 0))
  4668.               (label_ref (match_operand 0 "" ""))
  4669.               (pc)))]
  4670.   ""
  4671.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4672.  
  4673. (define_insn ""
  4674.   [(set (pc)
  4675.     (if_then_else (ge (cc0)
  4676.               (const_int 0))
  4677.               (label_ref (match_operand 0 "" ""))
  4678.               (pc)))]
  4679.   ""
  4680.   "*
  4681. {
  4682.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4683.     return AS1 (je,%l0);
  4684.  
  4685.   OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  4686. }")
  4687.  
  4688. (define_expand "bgeu"
  4689.   [(match_dup 1)
  4690.    (set (pc)
  4691.     (if_then_else (geu (cc0)
  4692.                (const_int 0))
  4693.               (label_ref (match_operand 0 "" ""))
  4694.               (pc)))]
  4695.   ""
  4696.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4697.  
  4698. (define_insn ""
  4699.   [(set (pc)
  4700.     (if_then_else (geu (cc0)
  4701.                (const_int 0))
  4702.               (label_ref (match_operand 0 "" ""))
  4703.               (pc)))]
  4704.   ""
  4705.   "jae %l0")
  4706.  
  4707. (define_expand "ble"
  4708.   [(match_dup 1)
  4709.    (set (pc)
  4710.     (if_then_else (le (cc0)
  4711.               (const_int 0))
  4712.               (label_ref (match_operand 0 "" ""))
  4713.               (pc)))]
  4714.   ""
  4715.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4716.  
  4717. (define_insn ""
  4718.   [(set (pc)
  4719.     (if_then_else (le (cc0)
  4720.               (const_int 0))
  4721.               (label_ref (match_operand 0 "" ""))
  4722.               (pc)))]
  4723.   ""
  4724.   "*
  4725. {
  4726.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4727.     return AS1 (jb,%l0);
  4728.  
  4729.   OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  4730. }")
  4731.  
  4732. (define_expand "bleu"
  4733.   [(match_dup 1)
  4734.    (set (pc)
  4735.     (if_then_else (leu (cc0)
  4736.                (const_int 0))
  4737.               (label_ref (match_operand 0 "" ""))
  4738.               (pc)))]
  4739.   ""
  4740.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4741.  
  4742. (define_insn ""
  4743.   [(set (pc)
  4744.     (if_then_else (leu (cc0)
  4745.                (const_int 0))
  4746.               (label_ref (match_operand 0 "" ""))
  4747.               (pc)))]
  4748.   ""
  4749.   "jbe %l0")
  4750.  
  4751. ;; Negated conditional jump instructions.
  4752.  
  4753. (define_insn ""
  4754.   [(set (pc)
  4755.     (if_then_else (eq (cc0)
  4756.               (const_int 0))
  4757.               (pc)
  4758.               (label_ref (match_operand 0 "" ""))))]
  4759.   ""
  4760.   "*
  4761. {
  4762.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4763.     return \"jc %l0\";
  4764.   else
  4765.     return \"jne %l0\";
  4766. }")
  4767.  
  4768. (define_insn ""
  4769.   [(set (pc)
  4770.     (if_then_else (ne (cc0)
  4771.               (const_int 0))
  4772.               (pc)
  4773.               (label_ref (match_operand 0 "" ""))))]
  4774.   ""
  4775.   "*
  4776. {
  4777.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4778.     return \"jnc %l0\";
  4779.   else
  4780.     return \"je %l0\";
  4781. }")
  4782.  
  4783. (define_insn ""
  4784.   [(set (pc)
  4785.     (if_then_else (gt (cc0)
  4786.               (const_int 0))
  4787.               (pc)
  4788.               (label_ref (match_operand 0 "" ""))))]
  4789.   ""
  4790.   "*
  4791. {
  4792.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4793.     return AS1 (jne,%l0);
  4794.  
  4795.   OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  4796. }")
  4797.  
  4798. (define_insn ""
  4799.   [(set (pc)
  4800.     (if_then_else (gtu (cc0)
  4801.                (const_int 0))
  4802.               (pc)
  4803.               (label_ref (match_operand 0 "" ""))))]
  4804.   ""
  4805.   "jbe %l0")
  4806.  
  4807. (define_insn ""
  4808.   [(set (pc)
  4809.     (if_then_else (lt (cc0)
  4810.               (const_int 0))
  4811.               (pc)
  4812.               (label_ref (match_operand 0 "" ""))))]
  4813.   ""
  4814.   "*
  4815. {
  4816.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4817.     return AS1 (jne,%l0);
  4818.  
  4819.   OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  4820. }")
  4821.  
  4822. (define_insn ""
  4823.   [(set (pc)
  4824.     (if_then_else (ltu (cc0)
  4825.                (const_int 0))
  4826.               (pc)
  4827.               (label_ref (match_operand 0 "" ""))))]
  4828.   ""
  4829.   "jae %l0")
  4830.  
  4831. (define_insn ""
  4832.   [(set (pc)
  4833.     (if_then_else (ge (cc0)
  4834.               (const_int 0))
  4835.               (pc)
  4836.               (label_ref (match_operand 0 "" ""))))]
  4837.   ""
  4838.   "*
  4839. {
  4840.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4841.     return AS1 (jne,%l0);
  4842.  
  4843.   OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  4844. }")
  4845.  
  4846. (define_insn ""
  4847.   [(set (pc)
  4848.     (if_then_else (geu (cc0)
  4849.                (const_int 0))
  4850.               (pc)
  4851.               (label_ref (match_operand 0 "" ""))))]
  4852.   ""
  4853.   "jb %l0")
  4854.  
  4855. (define_insn ""
  4856.   [(set (pc)
  4857.     (if_then_else (le (cc0)
  4858.               (const_int 0))
  4859.               (pc)
  4860.               (label_ref (match_operand 0 "" ""))))]
  4861.   ""
  4862.   "*
  4863. {
  4864.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4865.     return AS1 (jae,%l0);
  4866.  
  4867.   OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
  4868. }")
  4869.  
  4870. (define_insn ""
  4871.   [(set (pc)
  4872.     (if_then_else (leu (cc0)
  4873.                (const_int 0))
  4874.               (pc)
  4875.               (label_ref (match_operand 0 "" ""))))]
  4876.   ""
  4877.   "ja %l0")
  4878.  
  4879. ;; Unconditional and other jump instructions
  4880.  
  4881. (define_insn "jump"
  4882.   [(set (pc)
  4883.     (label_ref (match_operand 0 "" "")))]
  4884.   ""
  4885.   "jmp %l0")
  4886.  
  4887. (define_insn "indirect_jump"
  4888.   [(set (pc) (match_operand:SI 0 "general_operand" "rm"))]
  4889.   ""
  4890.   "*
  4891. {
  4892.   CC_STATUS_INIT;
  4893.  
  4894.   return AS1 (jmp,%*%0);
  4895. }")
  4896.  
  4897. ;; Implement switch statements when generating PIC code.  Switches are
  4898. ;; implemented by `tablejump' when not using -fpic.
  4899.  
  4900. ;; Emit code here to do the range checking and make the index zero based.
  4901.  
  4902. (define_expand "casesi"
  4903.   [(set (match_dup 5)
  4904.     (minus:SI (match_operand:SI 0 "general_operand" "")
  4905.           (match_operand:SI 1 "general_operand" "")))
  4906.    (set (cc0)
  4907.     (compare:CC (match_dup 5)
  4908.             (match_operand:SI 2 "general_operand" "")))
  4909.    (set (pc)
  4910.     (if_then_else (gtu (cc0)
  4911.                (const_int 0))
  4912.               (label_ref (match_operand 4 "" ""))
  4913.               (pc)))
  4914.    (parallel
  4915.     [(set (pc)
  4916.       (minus:SI (reg:SI 3)
  4917.             (mem:SI (plus:SI (mult:SI (match_dup 5)
  4918.                           (const_int 4))
  4919.                      (label_ref (match_operand 3 "" ""))))))
  4920.      (clobber (match_scratch:SI 6 ""))])]
  4921.   "flag_pic"
  4922.   "
  4923. {
  4924.   operands[5] = gen_reg_rtx (SImode);
  4925.   current_function_uses_pic_offset_table = 1;
  4926. }")
  4927.  
  4928. ;; Implement a casesi insn.
  4929.  
  4930. ;; Each entry in the "addr_diff_vec" looks like this as the result of the
  4931. ;; two rules below:
  4932. ;; 
  4933. ;;     .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
  4934. ;; 
  4935. ;; 1. An expression involving an external reference may only use the
  4936. ;;    addition operator, and only with an assembly-time constant.
  4937. ;;    The example above satisfies this because ".-.L2" is a constant.
  4938. ;; 
  4939. ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
  4940. ;;    given the value of "GOT - .", where GOT is the actual address of
  4941. ;;    the Global Offset Table.  Therefore, the .long above actually
  4942. ;;    stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2".  The
  4943. ;;    expression "GOT - .L2" by itself would generate an error from as(1).
  4944. ;; 
  4945. ;; The pattern below emits code that looks like this:
  4946. ;; 
  4947. ;;     movl %ebx,reg
  4948. ;;     subl TABLE@GOTOFF(%ebx,index,4),reg
  4949. ;;     jmp reg
  4950. ;; 
  4951. ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
  4952. ;; the addr_diff_vec is known to be part of this module.
  4953. ;; 
  4954. ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
  4955. ;; evaluates to just ".L2".
  4956.  
  4957. (define_insn ""
  4958.   [(set (pc)
  4959.     (minus:SI (reg:SI 3)
  4960.           (mem:SI (plus:SI
  4961.                (mult:SI (match_operand:SI 0 "register_operand" "r")
  4962.                     (const_int 4))
  4963.                (label_ref (match_operand 1 "" ""))))))
  4964.    (clobber (match_scratch:SI 2 "=&r"))]
  4965.   ""
  4966.   "*
  4967. {
  4968.   rtx xops[4];
  4969.  
  4970.   xops[0] = operands[0];
  4971.   xops[1] = operands[1];
  4972.   xops[2] = operands[2];
  4973.   xops[3] = pic_offset_table_rtx;
  4974.  
  4975.   output_asm_insn (AS2 (mov%L2,%3,%2), xops);
  4976.   output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
  4977.   output_asm_insn (AS1 (jmp,%*%2), xops);
  4978.   ASM_OUTPUT_ALIGN_CODE (asm_out_file);
  4979.   RET;
  4980. }")
  4981.  
  4982. (define_insn "tablejump"
  4983.   [(set (pc) (match_operand:SI 0 "general_operand" "rm"))
  4984.    (use (label_ref (match_operand 1 "" "")))]
  4985.   ""
  4986.   "*
  4987. {
  4988.   CC_STATUS_INIT;
  4989.  
  4990.   return AS1 (jmp,%*%0);
  4991. }")
  4992.  
  4993. ;; Call insns.
  4994.  
  4995. ;; If generating PIC code, the predicate indirect_operand will fail
  4996. ;; for operands[0] containing symbolic references on all of the named
  4997. ;; call* patterns.  Each named pattern is followed by an unnamed pattern
  4998. ;; that matches any call to a symbolic CONST (ie, a symbol_ref).  The
  4999. ;; unnamed patterns are only used while generating PIC code, because
  5000. ;; otherwise the named patterns match.
  5001.  
  5002. ;; Call subroutine returning no value.
  5003.  
  5004. (define_expand "call_pop"
  5005.   [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
  5006.             (match_operand:SI 1 "general_operand" ""))
  5007.           (set (reg:SI 7)
  5008.            (plus:SI (reg:SI 7)
  5009.                 (match_operand:SI 3 "immediate_operand" "")))])]
  5010.   ""
  5011.   "
  5012. {
  5013.   rtx addr;
  5014.  
  5015.   if (flag_pic)
  5016.     current_function_uses_pic_offset_table = 1;
  5017.  
  5018.   /* With half-pic, force the address into a register.  */
  5019.   addr = XEXP (operands[0], 0);
  5020.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  5021.     XEXP (operands[0], 0) = force_reg (Pmode, addr);
  5022.  
  5023.   if (! expander_call_insn_operand (operands[0], QImode))
  5024.     operands[0]
  5025.       = change_address (operands[0], VOIDmode,
  5026.             copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
  5027. }")
  5028.  
  5029. (define_insn ""
  5030.   [(call (match_operand:QI 0 "call_insn_operand" "m")
  5031.      (match_operand:SI 1 "general_operand" "g"))
  5032.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  5033.                 (match_operand:SI 3 "immediate_operand" "i")))]
  5034.   ""
  5035.   "*
  5036. {
  5037.   if (GET_CODE (operands[0]) == MEM
  5038.       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  5039.     {
  5040.       operands[0] = XEXP (operands[0], 0);
  5041.       return AS1 (call,%*%0);
  5042.     }
  5043.   else
  5044.     return AS1 (call,%P0);
  5045. }")
  5046.  
  5047. (define_insn ""
  5048.   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  5049.      (match_operand:SI 1 "general_operand" "g"))
  5050.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  5051.                 (match_operand:SI 3 "immediate_operand" "i")))]
  5052.   "!HALF_PIC_P ()"
  5053.   "call %P0")
  5054.  
  5055. (define_expand "call"
  5056.   [(call (match_operand:QI 0 "indirect_operand" "")
  5057.      (match_operand:SI 1 "general_operand" ""))]
  5058.   ;; Operand 1 not used on the i386.
  5059.   ""
  5060.   "
  5061. {
  5062.   rtx addr;
  5063.  
  5064.   if (flag_pic)
  5065.     current_function_uses_pic_offset_table = 1;
  5066.  
  5067.   /* With half-pic, force the address into a register.  */
  5068.   addr = XEXP (operands[0], 0);
  5069.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  5070.     XEXP (operands[0], 0) = force_reg (Pmode, addr);
  5071.  
  5072.   if (! expander_call_insn_operand (operands[0], QImode))
  5073.     operands[0]
  5074.       = change_address (operands[0], VOIDmode,
  5075.             copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
  5076. }")
  5077.  
  5078. (define_insn ""
  5079.   [(call (match_operand:QI 0 "call_insn_operand" "m")
  5080.      (match_operand:SI 1 "general_operand" "g"))]
  5081.   ;; Operand 1 not used on the i386.
  5082.   ""
  5083.   "*
  5084. {
  5085.   if (GET_CODE (operands[0]) == MEM
  5086.       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  5087.     {
  5088.       operands[0] = XEXP (operands[0], 0);
  5089.       return AS1 (call,%*%0);
  5090.     }
  5091.   else
  5092.     return AS1 (call,%P0);
  5093. }")
  5094.  
  5095. (define_insn ""
  5096.   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  5097.      (match_operand:SI 1 "general_operand" "g"))]
  5098.   ;; Operand 1 not used on the i386.
  5099.   "!HALF_PIC_P ()"
  5100.   "call %P0")
  5101.  
  5102. ;; Call subroutine, returning value in operand 0
  5103. ;; (which must be a hard register).
  5104.  
  5105. (define_expand "call_value_pop"
  5106.   [(parallel [(set (match_operand 0 "" "")
  5107.            (call (match_operand:QI 1 "indirect_operand" "")
  5108.              (match_operand:SI 2 "general_operand" "")))
  5109.           (set (reg:SI 7)
  5110.            (plus:SI (reg:SI 7)
  5111.                 (match_operand:SI 4 "immediate_operand" "")))])]
  5112.   ""
  5113.   "
  5114. {
  5115.   rtx addr;
  5116.  
  5117.   if (flag_pic)
  5118.     current_function_uses_pic_offset_table = 1;
  5119.  
  5120.   /* With half-pic, force the address into a register.  */
  5121.   addr = XEXP (operands[1], 0);
  5122.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  5123.     XEXP (operands[1], 0) = force_reg (Pmode, addr);
  5124.  
  5125.   if (! expander_call_insn_operand (operands[1], QImode))
  5126.     operands[1]
  5127.       = change_address (operands[1], VOIDmode,
  5128.             copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  5129. }")
  5130.  
  5131. (define_insn ""
  5132.   [(set (match_operand 0 "" "=rf")
  5133.     (call (match_operand:QI 1 "call_insn_operand" "m")
  5134.           (match_operand:SI 2 "general_operand" "g")))
  5135.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  5136.                 (match_operand:SI 4 "immediate_operand" "i")))]
  5137.   ""
  5138.   "*
  5139. {
  5140.   if (GET_CODE (operands[1]) == MEM
  5141.       && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  5142.     {
  5143.       operands[1] = XEXP (operands[1], 0);
  5144.       output_asm_insn (AS1 (call,%*%1), operands);
  5145.     }
  5146.   else
  5147.     output_asm_insn (AS1 (call,%P1), operands);
  5148.  
  5149.   RET;
  5150. }")
  5151.  
  5152. (define_insn ""
  5153.   [(set (match_operand 0 "" "=rf")
  5154.     (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
  5155.           (match_operand:SI 2 "general_operand" "g")))
  5156.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  5157.                 (match_operand:SI 4 "immediate_operand" "i")))]
  5158.   "!HALF_PIC_P ()"
  5159.   "call %P1")
  5160.  
  5161. (define_expand "call_value"
  5162.   [(set (match_operand 0 "" "")
  5163.     (call (match_operand:QI 1 "indirect_operand" "")
  5164.           (match_operand:SI 2 "general_operand" "")))]
  5165.   ;; Operand 2 not used on the i386.
  5166.   ""
  5167.   "
  5168. {
  5169.   rtx addr;
  5170.  
  5171.   if (flag_pic)
  5172.     current_function_uses_pic_offset_table = 1;
  5173.  
  5174.   /* With half-pic, force the address into a register.  */
  5175.   addr = XEXP (operands[1], 0);
  5176.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  5177.     XEXP (operands[1], 0) = force_reg (Pmode, addr);
  5178.  
  5179.   if (! expander_call_insn_operand (operands[1], QImode))
  5180.     operands[1]
  5181.       = change_address (operands[1], VOIDmode,
  5182.             copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  5183. }")
  5184.  
  5185. (define_insn ""
  5186.   [(set (match_operand 0 "" "=rf")
  5187.     (call (match_operand:QI 1 "call_insn_operand" "m")
  5188.           (match_operand:SI 2 "general_operand" "g")))]
  5189.   ;; Operand 2 not used on the i386.
  5190.   ""
  5191.   "*
  5192. {
  5193.   if (GET_CODE (operands[1]) == MEM
  5194.       && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  5195.     {
  5196.       operands[1] = XEXP (operands[1], 0);
  5197.       output_asm_insn (AS1 (call,%*%1), operands);
  5198.     }
  5199.   else
  5200.     output_asm_insn (AS1 (call,%P1), operands);
  5201.  
  5202.   RET;
  5203. }")
  5204.  
  5205. (define_insn ""
  5206.   [(set (match_operand 0 "" "=rf")
  5207.     (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
  5208.           (match_operand:SI 2 "general_operand" "g")))]
  5209.   ;; Operand 2 not used on the i386.
  5210.   "!HALF_PIC_P ()"
  5211.   "call %P1")
  5212.  
  5213. ;; Call subroutine returning any type.
  5214.  
  5215. (define_expand "untyped_call"
  5216.   [(parallel [(call (match_operand 0 "" "")
  5217.             (const_int 0))
  5218.           (match_operand 1 "" "")
  5219.           (match_operand 2 "" "")])]
  5220.   ""
  5221.   "
  5222. {
  5223.   int i;
  5224.  
  5225.   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
  5226.  
  5227.   for (i = 0; i < XVECLEN (operands[2], 0); i++)
  5228.     {
  5229.       rtx set = XVECEXP (operands[2], 0, i);
  5230.       emit_move_insn (SET_DEST (set), SET_SRC (set));
  5231.     }
  5232.  
  5233.   /* The optimizer does not know that the call sets the function value
  5234.      registers we stored in the result block.  We avoid problems by
  5235.      claiming that all hard registers are used and clobbered at this
  5236.      point.  */
  5237.   emit_insn (gen_blockage ());
  5238.  
  5239.   DONE;
  5240. }")
  5241.  
  5242. ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
  5243. ;; all of memory.  This blocks insns from being moved across this point.
  5244.  
  5245. (define_insn "blockage"
  5246.   [(unspec_volatile [(const_int 0)] 0)]
  5247.   ""
  5248.   "")
  5249.  
  5250. ;; Insn emitted into the body of a function to return from a function.
  5251. ;; This is only done if the function's epilogue is known to be simple.
  5252. ;; See comments for simple_386_epilogue in i386.c.
  5253.  
  5254. (define_insn "return"
  5255.   [(return)]
  5256.   "simple_386_epilogue ()"
  5257.   "*
  5258. {
  5259.   function_epilogue (asm_out_file, get_frame_size ());
  5260.   RET;
  5261. }")
  5262.  
  5263. (define_insn "nop"
  5264.   [(const_int 0)]
  5265.   ""
  5266.   "nop")
  5267.  
  5268. (define_expand "movstrsi"
  5269.   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
  5270.            (match_operand:BLK 1 "memory_operand" ""))
  5271.           (use (match_operand:SI 2 "const_int_operand" ""))
  5272.           (use (match_operand:SI 3 "const_int_operand" ""))
  5273.           (clobber (match_scratch:SI 4 ""))
  5274.           (clobber (match_dup 5))
  5275.           (clobber (match_dup 6))])]
  5276.   ""
  5277.   "
  5278. {
  5279.   rtx addr0, addr1;
  5280.  
  5281.   if (GET_CODE (operands[2]) != CONST_INT)
  5282.     FAIL;
  5283.  
  5284.   addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
  5285.   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
  5286.  
  5287.   operands[5] = addr0;
  5288.   operands[6] = addr1;
  5289.  
  5290.   operands[0] = gen_rtx (MEM, BLKmode, addr0);
  5291.   operands[1] = gen_rtx (MEM, BLKmode, addr1);
  5292. }")
  5293.  
  5294. ;; It might seem that operands 0 & 1 could use predicate register_operand.
  5295. ;; But strength reduction might offset the MEM expression.  So we let
  5296. ;; reload put the address into %edi & %esi.
  5297.  
  5298. (define_insn ""
  5299.   [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
  5300.     (mem:BLK (match_operand:SI 1 "address_operand" "S")))
  5301.    (use (match_operand:SI 2 "const_int_operand" "n"))
  5302.    (use (match_operand:SI 3 "immediate_operand" "i"))
  5303.    (clobber (match_scratch:SI 4 "=&c"))
  5304.    (clobber (match_dup 0))
  5305.    (clobber (match_dup 1))]
  5306.   ""
  5307.   "*
  5308. {
  5309.   rtx xops[2];
  5310.  
  5311.   output_asm_insn (\"cld\", operands);
  5312.   if (GET_CODE (operands[2]) == CONST_INT)
  5313.     {
  5314.       if (INTVAL (operands[2]) & ~0x03)
  5315.     {
  5316.       xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
  5317.       xops[1] = operands[4];
  5318.  
  5319.       output_asm_insn (AS2 (mov%L1,%0,%1), xops);
  5320. #ifdef INTEL_SYNTAX
  5321.       output_asm_insn (\"rep movsd\", xops);
  5322. #else
  5323.       output_asm_insn (\"rep\;movsl\", xops);
  5324. #endif
  5325.     }
  5326.       if (INTVAL (operands[2]) & 0x02)
  5327.     output_asm_insn (\"movsw\", operands);
  5328.       if (INTVAL (operands[2]) & 0x01)
  5329.     output_asm_insn (\"movsb\", operands);
  5330.     }
  5331.   else
  5332.     abort ();
  5333.   RET;
  5334. }")
  5335.  
  5336. (define_expand "cmpstrsi"
  5337.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  5338.            (compare:SI (match_operand:BLK 1 "general_operand" "")
  5339.                    (match_operand:BLK 2 "general_operand" "")))
  5340.           (use (match_operand:SI 3 "general_operand" ""))
  5341.           (use (match_operand:SI 4 "immediate_operand" ""))
  5342.           (clobber (match_dup 5))
  5343.           (clobber (match_dup 6))
  5344.           (clobber (match_dup 3))])]
  5345.   ""
  5346.   "
  5347. {
  5348.   rtx addr1, addr2;
  5349.  
  5350.   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
  5351.   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
  5352.   operands[3] = copy_to_mode_reg (SImode, operands[3]);
  5353.  
  5354.   operands[5] = addr1;
  5355.   operands[6] = addr2;
  5356.  
  5357.   operands[1] = gen_rtx (MEM, BLKmode, addr1);
  5358.   operands[2] = gen_rtx (MEM, BLKmode, addr2);
  5359.  
  5360. }")
  5361.  
  5362. ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
  5363. ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
  5364.  
  5365. ;; It might seem that operands 0 & 1 could use predicate register_operand.
  5366. ;; But strength reduction might offset the MEM expression.  So we let
  5367. ;; reload put the address into %edi & %esi.
  5368.  
  5369. ;; ??? Most comparisons have a constant length, and it's therefore
  5370. ;; possible to know that the length is non-zero, and to avoid the extra
  5371. ;; code to handle zero-length compares.
  5372.  
  5373. (define_insn ""
  5374.   [(set (match_operand:SI 0 "general_operand" "=&r")
  5375.     (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
  5376.             (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
  5377.    (use (match_operand:SI 3 "register_operand" "c"))
  5378.    (use (match_operand:SI 4 "immediate_operand" "i"))
  5379.    (clobber (match_dup 1))
  5380.    (clobber (match_dup 2))
  5381.    (clobber (match_dup 3))]
  5382.   ""
  5383.   "*
  5384. {
  5385.   rtx xops[4], label;
  5386.  
  5387.   label = gen_label_rtx ();
  5388.  
  5389.   output_asm_insn (\"cld\", operands);
  5390.   output_asm_insn (AS2 (xor%L0,%0,%0), operands);
  5391.   output_asm_insn (\"repz\;cmps%B2\", operands);
  5392.   output_asm_insn (\"je %l0\", &label);
  5393.  
  5394.   xops[0] = operands[0];
  5395.   xops[1] = gen_rtx (MEM, QImode,
  5396.              gen_rtx (PLUS, SImode, operands[1], constm1_rtx));
  5397.   xops[2] = gen_rtx (MEM, QImode,
  5398.              gen_rtx (PLUS, SImode, operands[2], constm1_rtx));
  5399.   xops[3] = operands[3];
  5400.  
  5401.   output_asm_insn (AS2 (movz%B1%L0,%1,%0), xops);
  5402.   output_asm_insn (AS2 (movz%B2%L3,%2,%3), xops);
  5403.  
  5404.   output_asm_insn (AS2 (sub%L0,%3,%0), xops);
  5405.   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
  5406.   RET;
  5407. }")
  5408.  
  5409. (define_insn ""
  5410.   [(set (cc0)
  5411.     (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
  5412.             (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
  5413.    (use (match_operand:SI 2 "register_operand" "c"))
  5414.    (use (match_operand:SI 3 "immediate_operand" "i"))
  5415.    (clobber (match_dup 0))
  5416.    (clobber (match_dup 1))
  5417.    (clobber (match_dup 2))]
  5418.   ""
  5419.   "*
  5420. {
  5421.   rtx xops[2];
  5422.  
  5423.   cc_status.flags |= CC_NOT_SIGNED;
  5424.  
  5425.   xops[0] = gen_rtx (REG, QImode, 0);
  5426.   xops[1] = CONST0_RTX (QImode);
  5427.  
  5428.   output_asm_insn (\"cld\", operands);
  5429.   output_asm_insn (AS2 (test%B0,%1,%0), xops);
  5430.   return \"repz\;cmps%B2\";
  5431. }")
  5432.  
  5433. (define_expand "ffssi2"
  5434.   [(set (match_dup 2)
  5435.     (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" ""))
  5436.          (const_int -1)))
  5437.    (set (match_operand:SI 0 "general_operand" "")
  5438.     (plus:SI (match_dup 2) (const_int 1)))]
  5439.   ""
  5440.   "operands[2] = gen_reg_rtx (SImode);")
  5441.  
  5442. (define_insn ""
  5443.   [(set (match_operand:SI 0 "general_operand" "=&r")
  5444.     (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" "rm"))
  5445.          (const_int -1)))]
  5446.   ""
  5447.   "*
  5448. {
  5449.   rtx xops[3];
  5450.   static int ffssi_label_number;
  5451.   char buffer[30];
  5452.  
  5453.   xops[0] = operands[0];
  5454.   xops[1] = operands[1];
  5455.   xops[2] = constm1_rtx;
  5456.   /* Can there be a way to avoid the jump here?  */
  5457.   output_asm_insn (AS2 (bsf%L0,%1,%0), xops);
  5458. #ifdef LOCAL_LABEL_PREFIX
  5459.   sprintf (buffer, \"jnz %sLFFSSI%d\",
  5460.        LOCAL_LABEL_PREFIX, ffssi_label_number);
  5461. #else
  5462.   sprintf (buffer, \"jnz %sLFFSSI%d\",
  5463.        \"\", ffssi_label_number);
  5464. #endif
  5465.   output_asm_insn (buffer, xops);
  5466.   output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  5467. #ifdef LOCAL_LABEL_PREFIX
  5468.   sprintf (buffer, \"%sLFFSSI%d:\",
  5469.        LOCAL_LABEL_PREFIX, ffssi_label_number);
  5470. #else
  5471.   sprintf (buffer, \"%sLFFSSI%d:\",
  5472.        \"\", ffssi_label_number);
  5473. #endif
  5474.   output_asm_insn (buffer, xops);
  5475.  
  5476.   ffssi_label_number++;
  5477.   return \"\";
  5478. }")
  5479.  
  5480. (define_expand "ffshi2"
  5481.   [(set (match_dup 2)
  5482.     (plus:HI (ffs:HI (match_operand:HI 1 "general_operand" ""))
  5483.          (const_int -1)))
  5484.    (set (match_operand:HI 0 "general_operand" "")
  5485.     (plus:HI (match_dup 2) (const_int 1)))]
  5486.   ""
  5487.   "operands[2] = gen_reg_rtx (HImode);")
  5488.  
  5489. (define_insn ""
  5490.   [(set (match_operand:HI 0 "general_operand" "=&r")
  5491.     (plus:HI (ffs:HI (match_operand:SI 1 "general_operand" "rm"))
  5492.          (const_int -1)))]
  5493.   ""
  5494.   "*
  5495. {
  5496.   rtx xops[3];
  5497.   static int ffshi_label_number;
  5498.   char buffer[30];
  5499.  
  5500.   xops[0] = operands[0];
  5501.   xops[1] = operands[1];
  5502.   xops[2] = constm1_rtx;
  5503.   output_asm_insn (AS2 (bsf%W0,%1,%0), xops);
  5504. #ifdef LOCAL_LABEL_PREFIX
  5505.   sprintf (buffer, \"jnz %sLFFSHI%d\",
  5506.        LOCAL_LABEL_PREFIX, ffshi_label_number);
  5507. #else
  5508.   sprintf (buffer, \"jnz %sLFFSHI%d\",
  5509.        \"\", ffshi_label_number);
  5510. #endif
  5511.   output_asm_insn (buffer, xops);
  5512.   output_asm_insn (AS2 (mov%W0,%2,%0), xops);
  5513. #ifdef LOCAL_LABEL_PREFIX
  5514.   sprintf (buffer, \"%sLFFSHI%d:\",
  5515.        LOCAL_LABEL_PREFIX, ffshi_label_number);
  5516. #else
  5517.   sprintf (buffer, \"%sLFFSHI%d:\",
  5518.        \"\", ffshi_label_number);
  5519. #endif
  5520.   output_asm_insn (buffer, xops);
  5521.  
  5522.   ffshi_label_number++;
  5523.   return \"\";
  5524. }")
  5525.  
  5526. ;; These patterns match the binary 387 instructions for addM3, subM3,
  5527. ;; mulM3 and divM3.  There are three patterns for each of DFmode and
  5528. ;; SFmode.  The first is the normal insn, the second the same insn but
  5529. ;; with one operand a conversion, and the third the same insn but with
  5530. ;; the other operand a conversion.  The conversion may be SFmode or
  5531. ;; SImode if the target mode DFmode, but only SImode if the target mode
  5532. ;; is SFmode.
  5533.  
  5534. (define_insn ""
  5535.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  5536.     (match_operator:DF 3 "binary_387_op"
  5537.             [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
  5538.              (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
  5539.   "TARGET_80387"
  5540.   "* return output_387_binary_op (insn, operands);")
  5541.  
  5542. (define_insn ""
  5543.   [(set (match_operand:DF 0 "register_operand" "=f")
  5544.     (match_operator:DF 3 "binary_387_op"
  5545.        [(float:DF (match_operand:SI 1 "general_operand" "rm"))
  5546.         (match_operand:DF 2 "general_operand" "0")]))]
  5547.   "TARGET_80387"
  5548.   "* return output_387_binary_op (insn, operands);")
  5549.  
  5550. (define_insn ""
  5551.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  5552.     (match_operator:XF 3 "binary_387_op"
  5553.             [(match_operand:XF 1 "nonimmediate_operand" "0,f")
  5554.              (match_operand:XF 2 "nonimmediate_operand" "f,0")]))]
  5555.   "TARGET_80387"
  5556.   "* return output_387_binary_op (insn, operands);")
  5557.  
  5558. (define_insn ""
  5559.   [(set (match_operand:XF 0 "register_operand" "=f")
  5560.     (match_operator:XF 3 "binary_387_op"
  5561.        [(float:XF (match_operand:SI 1 "general_operand" "rm"))
  5562.         (match_operand:XF 2 "general_operand" "0")]))]
  5563.   "TARGET_80387"
  5564.   "* return output_387_binary_op (insn, operands);")
  5565.  
  5566. (define_insn ""
  5567.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  5568.     (match_operator:XF 3 "binary_387_op"
  5569.        [(float_extend:XF (match_operand:SF 1 "general_operand" "fm,0"))
  5570.         (match_operand:XF 2 "general_operand" "0,f")]))]
  5571.   "TARGET_80387"
  5572.   "* return output_387_binary_op (insn, operands);")
  5573.  
  5574. (define_insn ""
  5575.   [(set (match_operand:XF 0 "register_operand" "=f")
  5576.     (match_operator:XF 3 "binary_387_op"
  5577.       [(match_operand:XF 1 "general_operand" "0")
  5578.        (float:XF (match_operand:SI 2 "general_operand" "rm"))]))]
  5579.   "TARGET_80387"
  5580.   "* return output_387_binary_op (insn, operands);")
  5581.  
  5582. (define_insn ""
  5583.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  5584.     (match_operator:XF 3 "binary_387_op"
  5585.       [(match_operand:XF 1 "general_operand" "0,f")
  5586.        (float_extend:XF
  5587.         (match_operand:SF 2 "general_operand" "fm,0"))]))]
  5588.   "TARGET_80387"
  5589.   "* return output_387_binary_op (insn, operands);")
  5590.  
  5591. (define_insn ""
  5592.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  5593.     (match_operator:DF 3 "binary_387_op"
  5594.        [(float_extend:DF (match_operand:SF 1 "general_operand" "fm,0"))
  5595.         (match_operand:DF 2 "general_operand" "0,f")]))]
  5596.   "TARGET_80387"
  5597.   "* return output_387_binary_op (insn, operands);")
  5598.  
  5599. (define_insn ""
  5600.   [(set (match_operand:DF 0 "register_operand" "=f")
  5601.     (match_operator:DF 3 "binary_387_op"
  5602.       [(match_operand:DF 1 "general_operand" "0")
  5603.        (float:DF (match_operand:SI 2 "general_operand" "rm"))]))]
  5604.   "TARGET_80387"
  5605.   "* return output_387_binary_op (insn, operands);")
  5606.  
  5607. (define_insn ""
  5608.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  5609.     (match_operator:DF 3 "binary_387_op"
  5610.       [(match_operand:DF 1 "general_operand" "0,f")
  5611.        (float_extend:DF
  5612.         (match_operand:SF 2 "general_operand" "fm,0"))]))]
  5613.   "TARGET_80387"
  5614.   "* return output_387_binary_op (insn, operands);")
  5615.  
  5616. (define_insn ""
  5617.   [(set (match_operand:SF 0 "register_operand" "=f,f")
  5618.     (match_operator:SF 3 "binary_387_op"
  5619.             [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
  5620.              (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
  5621.   "TARGET_80387"
  5622.   "* return output_387_binary_op (insn, operands);")
  5623.  
  5624. (define_insn ""
  5625.   [(set (match_operand:SF 0 "register_operand" "=f")
  5626.     (match_operator:SF 3 "binary_387_op"
  5627.       [(float:SF (match_operand:SI 1 "general_operand" "rm"))
  5628.        (match_operand:SF 2 "general_operand" "0")]))]
  5629.   "TARGET_80387"
  5630.   "* return output_387_binary_op (insn, operands);")
  5631.  
  5632. (define_insn ""
  5633.   [(set (match_operand:SF 0 "register_operand" "=f")
  5634.     (match_operator:SF 3 "binary_387_op"
  5635.       [(match_operand:SF 1 "general_operand" "0")
  5636.        (float:SF (match_operand:SI 2 "general_operand" "rm"))]))]
  5637.   "TARGET_80387"
  5638.   "* return output_387_binary_op (insn, operands);")
  5639.  
  5640. (define_expand "strlensi"
  5641.   [(parallel [(set (match_dup 4)
  5642.            (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
  5643.                    (match_operand:QI 2 "register_operand" "")
  5644.                    (match_operand:SI 3 "immediate_operand" "")] 0))
  5645.           (clobber (match_dup 1))])
  5646.    (set (match_dup 5)
  5647.     (not:SI (match_dup 4)))
  5648.    (set (match_operand:SI 0 "register_operand" "")
  5649.     (minus:SI (match_dup 5)
  5650.          (const_int 1)))]
  5651.   ""
  5652.   "
  5653. {
  5654.   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
  5655.   operands[4] = gen_reg_rtx (SImode);
  5656.   operands[5] = gen_reg_rtx (SImode);
  5657. }")
  5658.  
  5659. ;; It might seem that operands 0 & 1 could use predicate register_operand.
  5660. ;; But strength reduction might offset the MEM expression.  So we let
  5661. ;; reload put the address into %edi.
  5662.  
  5663. (define_insn ""
  5664.   [(set (match_operand:SI 0 "register_operand" "=&c")
  5665.     (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
  5666.             (match_operand:QI 2 "register_operand" "a")
  5667.             (match_operand:SI 3 "immediate_operand" "i")] 0))
  5668.    (clobber (match_dup 1))]
  5669.   ""
  5670.   "*
  5671. {
  5672.   rtx xops[2];
  5673.  
  5674.   xops[0] = operands[0];
  5675.   xops[1] = constm1_rtx;
  5676.   output_asm_insn (\"cld\", operands);
  5677.   output_asm_insn (AS2 (mov%L0,%1,%0), xops);
  5678.   return \"repnz\;scas%B2\";
  5679. }")
  5680.